From 41fc8a0cdcc2589f12ec28e6d0cfbae0bfdfb41a Mon Sep 17 00:00:00 2001 From: Paul Nasrat Date: Fri, 16 Feb 2007 16:24:52 +0000 Subject: [PATCH] Remove internal sqlite --- sqlite/.cvsignore | 23 - sqlite/Makefile.in | 651 -- sqlite/VERSION | 1 - sqlite/configure | 21326 ----------------------------------- sqlite/configure.ac | 611 - sqlite/main.mk | 548 - sqlite/mkopcodec.awk | 28 - sqlite/mkopcodeh.awk | 78 - sqlite/mkso.sh | 29 - sqlite/sqlite3.1 | 203 - sqlite/src/attach.c | 338 - sqlite/src/auth.c | 224 - sqlite/src/btree.c | 5729 ---------- sqlite/src/btree.h | 142 - sqlite/src/build.c | 3173 ------ sqlite/src/date.c | 1000 -- sqlite/src/delete.c | 443 - sqlite/src/experimental.c | 38 - sqlite/src/expr.c | 2173 ---- sqlite/src/func.c | 1195 -- sqlite/src/hash.c | 387 - sqlite/src/insert.c | 1111 -- sqlite/src/main.c | 1389 --- sqlite/src/os.h | 182 - sqlite/src/os_test.c | 463 - sqlite/src/os_unix.c | 1309 --- sqlite/src/os_win.c | 766 -- sqlite/src/pager.c | 3519 ------ sqlite/src/pager.h | 111 - sqlite/src/parse.y | 971 -- sqlite/src/pragma.c | 912 -- sqlite/src/printf.c | 831 -- sqlite/src/select.c | 2877 ----- sqlite/src/shell.c | 1801 --- sqlite/src/sqlite.h.in | 1226 -- sqlite/src/sqliteInt.h | 1549 --- sqlite/src/tclsqlite.c | 1758 --- sqlite/src/test1.c | 2993 ----- sqlite/src/test2.c | 598 - sqlite/src/test3.c | 1460 --- sqlite/src/test5.c | 218 - sqlite/src/tokenize.c | 664 -- sqlite/src/trigger.c | 788 -- sqlite/src/update.c | 468 - sqlite/src/utf.c | 570 - sqlite/src/util.c | 969 -- sqlite/src/vacuum.c | 300 - sqlite/src/vdbe.c | 4660 -------- sqlite/src/vdbe.h | 131 - sqlite/src/vdbeInt.h | 412 - sqlite/src/vdbeapi.c | 624 - sqlite/src/vdbeaux.c | 1849 --- sqlite/src/vdbemem.c | 735 -- sqlite/src/where.c | 1442 --- sqlite/tclinstaller.tcl | 29 - sqlite/test/all.test | 132 - sqlite/test/alter.test | 521 - sqlite/test/attach.test | 706 -- sqlite/test/attach2.test | 369 - sqlite/test/attach3.test | 243 - sqlite/test/auth.test | 2122 ---- sqlite/test/autoinc.test | 488 - sqlite/test/autovacuum.test | 491 - sqlite/test/autovacuum_crash.test | 58 - sqlite/test/autovacuum_ioerr.test | 58 - sqlite/test/autovacuum_ioerr2.test | 120 - sqlite/test/bigfile.test | 181 - sqlite/test/bind.test | 501 - sqlite/test/blob.test | 123 - sqlite/test/btree.test | 1161 -- sqlite/test/btree2.test | 497 - sqlite/test/btree7.test | 50 - sqlite/test/capi2.test | 651 -- sqlite/test/capi3.test | 826 -- sqlite/test/collate2.test | 613 - sqlite/test/collate3.test | 428 - sqlite/test/collate4.test | 700 -- sqlite/test/collate5.test | 270 - sqlite/test/collate6.test | 111 - sqlite/test/corrupt.test | 169 - sqlite/test/corrupt2.test | 109 - sqlite/test/crash.test | 432 - sqlite/test/date.test | 269 - sqlite/test/delete.test | 309 - sqlite/test/delete2.test | 99 - sqlite/test/enc.test | 152 - sqlite/test/enc2.test | 458 - sqlite/test/enc3.test | 57 - sqlite/test/expr.test | 564 - sqlite/test/fkey1.test | 58 - sqlite/test/func.test | 479 - sqlite/test/in.test | 311 - sqlite/test/index.test | 692 -- sqlite/test/index2.test | 74 - sqlite/test/index3.test | 43 - sqlite/test/insert.test | 345 - sqlite/test/insert2.test | 268 - sqlite/test/insert3.test | 135 - sqlite/test/interrupt.test | 189 - sqlite/test/intpkey.test | 523 - sqlite/test/ioerr.test | 189 - sqlite/test/join.test | 436 - sqlite/test/join2.test | 75 - sqlite/test/join3.test | 62 - sqlite/test/join4.test | 79 - sqlite/test/lastinsert.test | 346 - sqlite/test/laststmtchanges.test | 270 - sqlite/test/limit.test | 428 - sqlite/test/lock.test | 321 - sqlite/test/lock2.test | 159 - sqlite/test/main.test | 303 - sqlite/test/malloc.test | 386 - sqlite/test/memdb.test | 378 - sqlite/test/memleak.test | 97 - sqlite/test/minmax.test | 384 - sqlite/test/misc1.test | 564 - sqlite/test/misc2.test | 251 - sqlite/test/misc3.test | 317 - sqlite/test/misc4.test | 177 - sqlite/test/misuse.test | 207 - sqlite/test/null.test | 242 - sqlite/test/pager.test | 528 - sqlite/test/pager2.test | 408 - sqlite/test/pager3.test | 71 - sqlite/test/pagesize.test | 171 - sqlite/test/pragma.test | 763 -- sqlite/test/progress.test | 132 - sqlite/test/quick.test | 58 - sqlite/test/reindex.test | 172 - sqlite/test/rollback.test | 78 - sqlite/test/rowid.test | 674 -- sqlite/test/safety.test | 69 - sqlite/test/schema.test | 336 - sqlite/test/select1.test | 803 -- sqlite/test/select2.test | 184 - sqlite/test/select4.test | 514 - sqlite/test/select5.test | 156 - sqlite/test/select6.test | 457 - sqlite/test/select7.test | 73 - sqlite/test/sort.test | 435 - sqlite/test/subquery.test | 333 - sqlite/test/subselect.test | 178 - sqlite/test/table.test | 660 -- sqlite/test/tableapi.test | 213 - sqlite/test/tclsqlite.test | 303 - sqlite/test/tester.tcl | 424 - sqlite/test/trigger1.test | 575 - sqlite/test/trigger2.test | 728 -- sqlite/test/trigger3.test | 176 - sqlite/test/trigger4.test | 133 - sqlite/test/trigger5.test | 43 - sqlite/test/trigger6.test | 82 - sqlite/test/types.test | 308 - sqlite/test/types2.test | 313 - sqlite/test/update.test | 596 - sqlite/test/vacuum.test | 352 - sqlite/test/view.test | 443 - sqlite/test/where.test | 842 -- sqlite/tool/lemon.c | 4588 -------- sqlite/tool/lempar.c | 714 -- sqlite/tool/memleak.awk | 29 - sqlite/tool/memleak3.tcl | 108 - sqlite/tool/mkkeywordhash.c | 486 - sqlite/tool/spaceanal.tcl | 801 -- sqlite/www/autoinc.tcl | 109 - sqlite/www/c_interface.tcl | 1116 -- sqlite/www/capi3.tcl | 453 - sqlite/www/capi3ref.tcl | 1137 -- sqlite/www/changes.tcl | 1258 --- sqlite/www/common.tcl | 88 - sqlite/www/compile.tcl | 272 - sqlite/www/datatype3.tcl | 421 - sqlite/www/different.tcl | 140 - sqlite/www/docs.tcl | 127 - sqlite/www/download.tcl | 151 - sqlite/www/faq.tcl | 505 - sqlite/www/index.tcl | 106 - sqlite/www/lang.tcl | 1804 --- sqlite/www/oldnews.tcl | 162 - sqlite/www/omitted.tcl | 94 - sqlite/www/optimizing.tcl | 15 - sqlite/www/pragma.tcl | 443 - sqlite/www/quickstart.tcl | 108 - sqlite/www/speed.tcl | 495 - sqlite/www/support.tcl | 79 - sqlite/www/tclsqlite.tcl | 485 - sqlite/www/vdbe.tcl | 1983 ---- sqlite/www/whentouse.tcl | 252 - 188 files changed, 132164 deletions(-) delete mode 100644 sqlite/.cvsignore delete mode 100644 sqlite/Makefile.in delete mode 100644 sqlite/VERSION delete mode 100755 sqlite/configure delete mode 100644 sqlite/configure.ac delete mode 100644 sqlite/main.mk delete mode 100644 sqlite/mkopcodec.awk delete mode 100644 sqlite/mkopcodeh.awk delete mode 100644 sqlite/mkso.sh delete mode 100644 sqlite/sqlite3.1 delete mode 100644 sqlite/src/attach.c delete mode 100644 sqlite/src/auth.c delete mode 100644 sqlite/src/btree.c delete mode 100644 sqlite/src/btree.h delete mode 100644 sqlite/src/build.c delete mode 100644 sqlite/src/date.c delete mode 100644 sqlite/src/delete.c delete mode 100644 sqlite/src/experimental.c delete mode 100644 sqlite/src/expr.c delete mode 100644 sqlite/src/func.c delete mode 100644 sqlite/src/hash.c delete mode 100644 sqlite/src/insert.c delete mode 100644 sqlite/src/main.c delete mode 100644 sqlite/src/os.h delete mode 100644 sqlite/src/os_test.c delete mode 100644 sqlite/src/os_unix.c delete mode 100644 sqlite/src/os_win.c delete mode 100644 sqlite/src/pager.c delete mode 100644 sqlite/src/pager.h delete mode 100644 sqlite/src/parse.y delete mode 100644 sqlite/src/pragma.c delete mode 100644 sqlite/src/printf.c delete mode 100644 sqlite/src/select.c delete mode 100644 sqlite/src/shell.c delete mode 100644 sqlite/src/sqlite.h.in delete mode 100644 sqlite/src/sqliteInt.h delete mode 100644 sqlite/src/tclsqlite.c delete mode 100644 sqlite/src/test1.c delete mode 100644 sqlite/src/test2.c delete mode 100644 sqlite/src/test3.c delete mode 100644 sqlite/src/test5.c delete mode 100644 sqlite/src/tokenize.c delete mode 100644 sqlite/src/trigger.c delete mode 100644 sqlite/src/update.c delete mode 100644 sqlite/src/utf.c delete mode 100644 sqlite/src/util.c delete mode 100644 sqlite/src/vacuum.c delete mode 100644 sqlite/src/vdbe.c delete mode 100644 sqlite/src/vdbe.h delete mode 100644 sqlite/src/vdbeInt.h delete mode 100644 sqlite/src/vdbeapi.c delete mode 100644 sqlite/src/vdbeaux.c delete mode 100644 sqlite/src/vdbemem.c delete mode 100644 sqlite/src/where.c delete mode 100644 sqlite/tclinstaller.tcl delete mode 100644 sqlite/test/all.test delete mode 100644 sqlite/test/alter.test delete mode 100644 sqlite/test/attach.test delete mode 100644 sqlite/test/attach2.test delete mode 100644 sqlite/test/attach3.test delete mode 100644 sqlite/test/auth.test delete mode 100644 sqlite/test/autoinc.test delete mode 100644 sqlite/test/autovacuum.test delete mode 100644 sqlite/test/autovacuum_crash.test delete mode 100644 sqlite/test/autovacuum_ioerr.test delete mode 100644 sqlite/test/autovacuum_ioerr2.test delete mode 100644 sqlite/test/bigfile.test delete mode 100644 sqlite/test/bind.test delete mode 100644 sqlite/test/blob.test delete mode 100644 sqlite/test/btree.test delete mode 100644 sqlite/test/btree2.test delete mode 100644 sqlite/test/btree7.test delete mode 100644 sqlite/test/capi2.test delete mode 100644 sqlite/test/capi3.test delete mode 100644 sqlite/test/collate2.test delete mode 100644 sqlite/test/collate3.test delete mode 100644 sqlite/test/collate4.test delete mode 100644 sqlite/test/collate5.test delete mode 100644 sqlite/test/collate6.test delete mode 100644 sqlite/test/corrupt.test delete mode 100644 sqlite/test/corrupt2.test delete mode 100644 sqlite/test/crash.test delete mode 100644 sqlite/test/date.test delete mode 100644 sqlite/test/delete.test delete mode 100644 sqlite/test/delete2.test delete mode 100644 sqlite/test/enc.test delete mode 100644 sqlite/test/enc2.test delete mode 100644 sqlite/test/enc3.test delete mode 100644 sqlite/test/expr.test delete mode 100644 sqlite/test/fkey1.test delete mode 100644 sqlite/test/func.test delete mode 100644 sqlite/test/in.test delete mode 100644 sqlite/test/index.test delete mode 100644 sqlite/test/index2.test delete mode 100644 sqlite/test/index3.test delete mode 100644 sqlite/test/insert.test delete mode 100644 sqlite/test/insert2.test delete mode 100644 sqlite/test/insert3.test delete mode 100644 sqlite/test/interrupt.test delete mode 100644 sqlite/test/intpkey.test delete mode 100644 sqlite/test/ioerr.test delete mode 100644 sqlite/test/join.test delete mode 100644 sqlite/test/join2.test delete mode 100644 sqlite/test/join3.test delete mode 100644 sqlite/test/join4.test delete mode 100644 sqlite/test/lastinsert.test delete mode 100644 sqlite/test/laststmtchanges.test delete mode 100644 sqlite/test/limit.test delete mode 100644 sqlite/test/lock.test delete mode 100644 sqlite/test/lock2.test delete mode 100644 sqlite/test/main.test delete mode 100644 sqlite/test/malloc.test delete mode 100644 sqlite/test/memdb.test delete mode 100644 sqlite/test/memleak.test delete mode 100644 sqlite/test/minmax.test delete mode 100644 sqlite/test/misc1.test delete mode 100644 sqlite/test/misc2.test delete mode 100644 sqlite/test/misc3.test delete mode 100644 sqlite/test/misc4.test delete mode 100644 sqlite/test/misuse.test delete mode 100644 sqlite/test/null.test delete mode 100644 sqlite/test/pager.test delete mode 100644 sqlite/test/pager2.test delete mode 100644 sqlite/test/pager3.test delete mode 100644 sqlite/test/pagesize.test delete mode 100644 sqlite/test/pragma.test delete mode 100755 sqlite/test/progress.test delete mode 100644 sqlite/test/quick.test delete mode 100644 sqlite/test/reindex.test delete mode 100644 sqlite/test/rollback.test delete mode 100644 sqlite/test/rowid.test delete mode 100644 sqlite/test/safety.test delete mode 100644 sqlite/test/schema.test delete mode 100644 sqlite/test/select1.test delete mode 100644 sqlite/test/select2.test delete mode 100644 sqlite/test/select4.test delete mode 100644 sqlite/test/select5.test delete mode 100644 sqlite/test/select6.test delete mode 100644 sqlite/test/select7.test delete mode 100644 sqlite/test/sort.test delete mode 100644 sqlite/test/subquery.test delete mode 100644 sqlite/test/subselect.test delete mode 100644 sqlite/test/table.test delete mode 100644 sqlite/test/tableapi.test delete mode 100644 sqlite/test/tclsqlite.test delete mode 100644 sqlite/test/tester.tcl delete mode 100644 sqlite/test/trigger1.test delete mode 100644 sqlite/test/trigger2.test delete mode 100644 sqlite/test/trigger3.test delete mode 100644 sqlite/test/trigger4.test delete mode 100644 sqlite/test/trigger5.test delete mode 100644 sqlite/test/trigger6.test delete mode 100644 sqlite/test/types.test delete mode 100644 sqlite/test/types2.test delete mode 100644 sqlite/test/update.test delete mode 100644 sqlite/test/vacuum.test delete mode 100644 sqlite/test/view.test delete mode 100644 sqlite/test/where.test delete mode 100644 sqlite/tool/lemon.c delete mode 100644 sqlite/tool/lempar.c delete mode 100644 sqlite/tool/memleak.awk delete mode 100644 sqlite/tool/memleak3.tcl delete mode 100644 sqlite/tool/mkkeywordhash.c delete mode 100644 sqlite/tool/spaceanal.tcl delete mode 100644 sqlite/www/autoinc.tcl delete mode 100644 sqlite/www/c_interface.tcl delete mode 100644 sqlite/www/capi3.tcl delete mode 100644 sqlite/www/capi3ref.tcl delete mode 100644 sqlite/www/changes.tcl delete mode 100644 sqlite/www/common.tcl delete mode 100644 sqlite/www/compile.tcl delete mode 100644 sqlite/www/datatype3.tcl delete mode 100644 sqlite/www/different.tcl delete mode 100644 sqlite/www/docs.tcl delete mode 100644 sqlite/www/download.tcl delete mode 100644 sqlite/www/faq.tcl delete mode 100644 sqlite/www/index.tcl delete mode 100644 sqlite/www/lang.tcl delete mode 100644 sqlite/www/oldnews.tcl delete mode 100644 sqlite/www/omitted.tcl delete mode 100644 sqlite/www/optimizing.tcl delete mode 100644 sqlite/www/pragma.tcl delete mode 100644 sqlite/www/quickstart.tcl delete mode 100644 sqlite/www/speed.tcl delete mode 100644 sqlite/www/support.tcl delete mode 100644 sqlite/www/tclsqlite.tcl delete mode 100644 sqlite/www/vdbe.tcl delete mode 100644 sqlite/www/whentouse.tcl diff --git a/sqlite/.cvsignore b/sqlite/.cvsignore deleted file mode 100644 index a858fba..0000000 --- a/sqlite/.cvsignore +++ /dev/null @@ -1,23 +0,0 @@ -.libs -Makefile -Makefile.in -config.h -config.log -config.status -keywordhash.h -lemon -lempar.c -libtool -mkkeywordhash -opcodes.c -opcodes.h -parse.c -parse.h -parse.out -parse.y -sqlite3 -sqlite3.h -sqlite3.pc -*.la -*.lo -*.swp diff --git a/sqlite/Makefile.in b/sqlite/Makefile.in deleted file mode 100644 index d8f84d2..0000000 --- a/sqlite/Makefile.in +++ /dev/null @@ -1,651 +0,0 @@ -#!/usr/make -# -# Makefile for SQLITE -# -# This makefile is suppose to be configured automatically using the -# autoconf. But if that does not work for you, you can configure -# the makefile manually. Just set the parameters below to values that -# work well for your system. -# -# If the configure script does not work out-of-the-box, you might -# be able to get it to work by giving it some hints. See the comment -# at the beginning of configure.in for additional information. -# - -# The toplevel directory of the source tree. This is the directory -# that contains this "Makefile.in" and the "configure.in" script. -# -TOP = @srcdir@ - -# C Compiler and options for use in building executables that -# will run on the platform that is doing the build. -# -BCC = @BUILD_CC@ @BUILD_CFLAGS@ - -# C Compile and options for use in building executables that -# will run on the target platform. (BCC and TCC are usually the -# same unless your are cross-compiling.) -# -TCC = @TARGET_CC@ @TARGET_CFLAGS@ -I. -I${TOP}/src - -# Define -DNDEBUG to compile without debugging (i.e., for production usage) -# Omitting the define will cause extra debugging code to be inserted and -# includes extra comments when "EXPLAIN stmt" is used. -# -TCC += @TARGET_DEBUG@ - -# Compiler options needed for programs that use the TCL library. -# -TCC += @TCL_INCLUDE_SPEC@ - -# The library that programs using TCL must link against. -# -LIBTCL = @TCL_LIB_SPEC@ @TCL_LIBS@ - -# Compiler options needed for programs that use the readline() library. -# -READLINE_FLAGS = -DHAVE_READLINE=@TARGET_HAVE_READLINE@ @TARGET_READLINE_INC@ - -# The library that programs using readline() must link against. -# -LIBREADLINE = @TARGET_READLINE_LIBS@ - -# Should the database engine be compiled threadsafe -# -THREADSAFE = -DTHREADSAFE=@THREADSAFE@ - -# The pthreads library if needed -# -LIBPTHREAD=@TARGET_THREAD_LIB@ - -# Flags controlling use of the in memory btree implementation -# -# TEMP_STORE is 0 to force temporary tables to be in a file, 1 to -# default to file, 2 to default to memory, and 3 to force temporary -# tables to always be in memory. -# -TEMP_STORE = -DTEMP_STORE=@TEMP_STORE@ - -# Version numbers and release number for the SQLite being compiled. -# -VERSION = @VERSION@ -VERSION_NUMBER = @VERSION_NUMBER@ -RELEASE = @RELEASE@ - -# Filename extensions -# -BEXE = @BUILD_EXEEXT@ -TEXE = @TARGET_EXEEXT@ - -# The following variable is "1" if the configure script was able to locate -# the tclConfig.sh file. It is an empty string otherwise. When this -# variable is "1", the TCL extension library (libtclsqlite3.so) is built -# and installed. -# -HAVE_TCL = @HAVE_TCL@ - -# The suffix used on shared libraries. Ex: ".dll", ".so", ".dylib" -# -SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ - -# The directory into which to store package information for - -# Some standard variables and programs -# -prefix = @prefix@ -exec_prefix = @exec_prefix@ -libdir = @libdir@ -INSTALL = @INSTALL@ -LIBTOOL = ./libtool -ALLOWRELEASE = @ALLOWRELEASE@ - -# libtool compile/link/install -LTCOMPILE = $(LIBTOOL) --mode=compile $(TCC) -LTLINK = $(LIBTOOL) --mode=link $(TCC) -LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) - -# You should not have to change anything below this line -############################################################################### - -OPTS += -DSQLITE_OMIT_CURSOR # Cursors do not work at this time -TCC += -DSQLITE_OMIT_CURSOR - -# Object files for the SQLite library. -# -LIBOBJ = attach.lo auth.lo btree.lo build.lo date.lo \ - delete.lo expr.lo func.lo hash.lo insert.lo \ - main.lo opcodes.lo os_unix.lo os_win.lo \ - pager.lo parse.lo pragma.lo printf.lo random.lo \ - select.lo table.lo tokenize.lo trigger.lo update.lo \ - util.lo vacuum.lo vdbe.lo vdbeapi.lo vdbeaux.lo vdbemem.lo \ - where.lo utf.lo legacy.lo - -# All of the source code files. -# -SRC = \ - $(TOP)/src/attach.c \ - $(TOP)/src/auth.c \ - $(TOP)/src/btree.c \ - $(TOP)/src/btree.h \ - $(TOP)/src/build.c \ - $(TOP)/src/date.c \ - $(TOP)/src/delete.c \ - $(TOP)/src/expr.c \ - $(TOP)/src/func.c \ - $(TOP)/src/hash.c \ - $(TOP)/src/hash.h \ - $(TOP)/src/insert.c \ - $(TOP)/src/legacy.c \ - $(TOP)/src/main.c \ - $(TOP)/src/os_unix.c \ - $(TOP)/src/os_win.c \ - $(TOP)/src/pager.c \ - $(TOP)/src/pager.h \ - $(TOP)/src/parse.y \ - $(TOP)/src/pragma.c \ - $(TOP)/src/printf.c \ - $(TOP)/src/random.c \ - $(TOP)/src/select.c \ - $(TOP)/src/shell.c \ - $(TOP)/src/sqlite.h.in \ - $(TOP)/src/sqliteInt.h \ - $(TOP)/src/table.c \ - $(TOP)/src/tclsqlite.c \ - $(TOP)/src/tokenize.c \ - $(TOP)/src/trigger.c \ - $(TOP)/src/utf.c \ - $(TOP)/src/update.c \ - $(TOP)/src/util.c \ - $(TOP)/src/vacuum.c \ - $(TOP)/src/vdbe.c \ - $(TOP)/src/vdbe.h \ - $(TOP)/src/vdbeapi.c \ - $(TOP)/src/vdbeaux.c \ - $(TOP)/src/vdbemem.c \ - $(TOP)/src/vdbeInt.h \ - $(TOP)/src/where.c - -# Source code to the test files. -# -TESTSRC = \ - $(TOP)/src/btree.c \ - $(TOP)/src/date.c \ - $(TOP)/src/func.c \ - $(TOP)/src/os_unix.c \ - $(TOP)/src/os_win.c \ - $(TOP)/src/pager.c \ - $(TOP)/src/pragma.c \ - $(TOP)/src/printf.c \ - $(TOP)/src/test1.c \ - $(TOP)/src/test2.c \ - $(TOP)/src/test3.c \ - $(TOP)/src/test4.c \ - $(TOP)/src/test5.c \ - $(TOP)/src/utf.c \ - $(TOP)/src/util.c \ - $(TOP)/src/vdbe.c \ - $(TOP)/src/md5.c - -# Header files used by all library source files. -# -HDR = \ - sqlite3.h \ - $(TOP)/src/btree.h \ - config.h \ - $(TOP)/src/hash.h \ - opcodes.h \ - $(TOP)/src/os.h \ - $(TOP)/src/os_common.h \ - $(TOP)/src/os_unix.h \ - $(TOP)/src/os_win.h \ - $(TOP)/src/sqliteInt.h \ - $(TOP)/src/vdbe.h \ - parse.h - -# Header files used by the VDBE submodule -# -VDBEHDR = \ - $(HDR) \ - $(TOP)/src/vdbeInt.h - -# This is the default Makefile target. The objects listed here -# are what get build when you type just "make" with no arguments. -# -all: sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la) - -Makefile: $(TOP)/Makefile.in - ./config.status - -# Generate the file "last_change" which contains the date of change -# of the most recently modified source code file -# -last_change: $(SRC) - cat $(SRC) | grep '$$Id: ' | sort +4 | tail -1 \ - | awk '{print $$5,$$6}' >last_change - -libsqlite3.la: $(LIBOBJ) - $(LTLINK) -o libsqlite3.la $(LIBOBJ) $(LIBPTHREAD) \ - ${ALLOWRELEASE} -rpath $(libdir) -version-info "8:6:8" - -libtclsqlite3.la: tclsqlite.lo libsqlite3.la - $(LTLINK) -o libtclsqlite3.la tclsqlite.lo \ - $(LIBOBJ) @TCL_STUB_LIB_SPEC@ $(LIBPTHREAD) \ - -rpath $(libdir)/sqlite \ - -version-info "8:6:8" - -sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h - $(LTLINK) $(READLINE_FLAGS) $(LIBPTHREAD) \ - -o sqlite3 $(TOP)/src/shell.c libsqlite3.la $(LIBREADLINE) - -# This target creates a directory named "tsrc" and fills it with -# copies of all of the C source code and header files needed to -# build on the target system. Some of the C source code and header -# files are automatically generated. This target takes care of -# all that automatic generation. -# -target_source: $(SRC) parse.c opcodes.c keywordhash.h $(VDBEHDR) - rm -rf tsrc - mkdir -p tsrc - cp $(SRC) $(VDBEHDR) tsrc - rm tsrc/sqlite.h.in tsrc/parse.y - cp parse.c opcodes.c keywordhash.h tsrc - cp $(TOP)/sqlite3.def tsrc - -# Rules to build the LEMON compiler generator -# -lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c - $(BCC) -o lemon $(TOP)/tool/lemon.c - cp $(TOP)/tool/lempar.c . - - -# Rules to build individual files -# -attach.lo: $(TOP)/src/attach.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/attach.c - -auth.lo: $(TOP)/src/auth.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/auth.c - -btree.lo: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h - $(LTCOMPILE) -c $(TOP)/src/btree.c - -build.lo: $(TOP)/src/build.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/build.c - -# The config.h file will contain a single #define that tells us how -# many bytes are in a pointer. This only works if a pointer is the -# same size on the host as it is on the target. If you are cross-compiling -# to a target with a different pointer size, you'll need to manually -# configure the config.h file. -# -config.h: - echo '#include ' >temp.c - echo 'int main(){printf(' >>temp.c - echo '"#define SQLITE_PTR_SZ %d",sizeof(char*));' >>temp.c - echo 'exit(0);}' >>temp.c - $(BCC) -o temp temp.c - ./temp >config.h - echo >>config.h - rm -f temp.c temp - -date.lo: $(TOP)/src/date.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/date.c - -delete.lo: $(TOP)/src/delete.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/delete.c - -expr.lo: $(TOP)/src/expr.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/expr.c - -func.lo: $(TOP)/src/func.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/func.c - -hash.lo: $(TOP)/src/hash.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/hash.c - -insert.lo: $(TOP)/src/insert.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/insert.c - -legacy.lo: $(TOP)/src/legacy.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/legacy.c - -main.lo: $(TOP)/src/main.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c - -pager.lo: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h - $(LTCOMPILE) -c $(TOP)/src/pager.c - -opcodes.lo: opcodes.c - $(LTCOMPILE) -c opcodes.c - -opcodes.c: opcodes.h $(TOP)/mkopcodec.awk - sort -n -b +2 opcodes.h | awk -f $(TOP)/mkopcodec.awk >opcodes.c - -opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk - cat parse.h $(TOP)/src/vdbe.c | awk -f $(TOP)/mkopcodeh.awk >opcodes.h - -os_unix.lo: $(TOP)/src/os_unix.c $(HDR) - $(LTCOMPILE) $(THREADSAFE) -c $(TOP)/src/os_unix.c - -os_win.lo: $(TOP)/src/os_win.c $(HDR) - $(LTCOMPILE) $(THREADSAFE) -c $(TOP)/src/os_win.c - -parse.lo: parse.c $(HDR) - $(LTCOMPILE) -c parse.c - -parse.h: parse.c - -parse.c: $(TOP)/src/parse.y lemon$(BEXE) - cp $(TOP)/src/parse.y . - ./lemon $(OPTS) parse.y - -pragma.lo: $(TOP)/src/pragma.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/pragma.c - -printf.lo: $(TOP)/src/printf.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/printf.c - -random.lo: $(TOP)/src/random.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/random.c - -select.lo: $(TOP)/src/select.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/select.c - -sqlite3.h: $(TOP)/src/sqlite.h.in - sed -e s/--VERS--/$(RELEASE)/ $(TOP)/src/sqlite.h.in | \ - sed -e s/--VERSION-NUMBER--/$(VERSION_NUMBER)/ >sqlite3.h - -table.lo: $(TOP)/src/table.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/table.c - -tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/tclsqlite.c - -tokenize.lo: $(TOP)/src/tokenize.c keywordhash.h $(HDR) - $(LTCOMPILE) -c $(TOP)/src/tokenize.c - -keywordhash.h: $(TOP)/tool/mkkeywordhash.c - $(BCC) -o mkkeywordhash$(BEXE) $(OPTS) $(TOP)/tool/mkkeywordhash.c - ./mkkeywordhash$(BEXE) >keywordhash.h - -trigger.lo: $(TOP)/src/trigger.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/trigger.c - -update.lo: $(TOP)/src/update.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/update.c - -utf.lo: $(TOP)/src/utf.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/utf.c - -util.lo: $(TOP)/src/util.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/util.c - -vacuum.lo: $(TOP)/src/vacuum.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/vacuum.c - -vdbe.lo: $(TOP)/src/vdbe.c $(VDBEHDR) - $(LTCOMPILE) -c $(TOP)/src/vdbe.c - -vdbeapi.lo: $(TOP)/src/vdbeapi.c $(VDBEHDR) - $(LTCOMPILE) -c $(TOP)/src/vdbeapi.c - -vdbeaux.lo: $(TOP)/src/vdbeaux.c $(VDBEHDR) - $(LTCOMPILE) -c $(TOP)/src/vdbeaux.c - -vdbemem.lo: $(TOP)/src/vdbemem.c $(VDBEHDR) - $(LTCOMPILE) -c $(TOP)/src/vdbemem.c - -where.lo: $(TOP)/src/where.c $(HDR) - $(LTCOMPILE) -c $(TOP)/src/where.c - -tclsqlite-shell.lo: $(TOP)/src/tclsqlite.c $(HDR) - $(LTCOMPILE) -DTCLSH=1 -o $@ -c $(TOP)/src/tclsqlite.c - -tclsqlite-stubs.lo: $(TOP)/src/tclsqlite.c $(HDR) - $(LTCOMPILE) -DTCL_USE_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c - -tclsqlite3: tclsqlite-shell.lo libsqlite3.la - $(LTLINK) -o tclsqlite3 tclsqlite-shell.lo \ - libsqlite3.la $(LIBTCL) - -testfixture$(TEXE): $(TOP)/src/tclsqlite.c libtclsqlite3.la libsqlite3.la $(TESTSRC) - $(LTLINK) -DTCLSH=1 -DSQLITE_TEST=1\ - $(THREADSAFE) $(TEMP_STORE)\ - -o testfixture $(TESTSRC) $(TOP)/src/tclsqlite.c \ - libtclsqlite3.la $(LIBTCL) - -crashtest$(TEXE): $(TOP)/src/tclsqlite.c libsqlite3.la $(TESTSRC) $(TOP)/src/os_test.c - $(LTLINK) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 \ - -o crashtest \ - $(TESTSRC) $(TOP)/src/os_test.c $(TOP)/src/tclsqlite.c \ - libsqlite3.la $(LIBTCL) $(THREADLIB) - - - -fulltest: testfixture$(TEXE) sqlite3$(TEXE) crashtest$(TEXE) - ./testfixture $(TOP)/test/all.test - -test: testfixture$(TEXE) sqlite3$(TEXE) - ./testfixture $(TOP)/test/quick.test - -sqlite3_analyzer$(TEXE): $(TOP)/src/tclsqlite.c libtclsqlite3.la \ - $(TESTSRC) $(TOP)/tool/spaceanal.tcl - sed \ - -e '/^#/d' \ - -e 's,\\,\\\\,g' \ - -e 's,",\\",g' \ - -e 's,^,",' \ - -e 's,$$,\\n",' \ - $(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h - $(LTLINK) -DTCLSH=2 -DSQLITE_TEST=1\ - $(THREADSAFE) $(TEMP_STORE)\ - -o sqlite3_analyzer$(EXE) $(TESTSRC) $(TOP)/src/tclsqlite.c \ - libtclsqlite3.la $(LIBTCL) - -# Rules used to build documentation -# -arch.html: $(TOP)/www/arch.tcl - tclsh $(TOP)/www/arch.tcl >arch.html - -arch2.gif: $(TOP)/www/arch2.gif - cp $(TOP)/www/arch2.gif . - -autoinc.html: $(TOP)/www/autoinc.tcl - tclsh $(TOP)/www/autoinc.tcl >autoinc.html - -c_interface.html: $(TOP)/www/c_interface.tcl - tclsh $(TOP)/www/c_interface.tcl >c_interface.html - -capi3.html: $(TOP)/www/capi3.tcl - tclsh $(TOP)/www/capi3.tcl >capi3.html - -capi3ref.html: $(TOP)/www/capi3ref.tcl - tclsh $(TOP)/www/capi3ref.tcl >capi3ref.html - -changes.html: $(TOP)/www/changes.tcl - tclsh $(TOP)/www/changes.tcl >changes.html - -compile.html: $(TOP)/www/compile.tcl - tclsh $(TOP)/www/compile.tcl >compile.html - -copyright.html: $(TOP)/www/copyright.tcl - tclsh $(TOP)/www/copyright.tcl >copyright.html - -copyright-release.html: $(TOP)/www/copyright-release.html - cp $(TOP)/www/copyright-release.html . - -copyright-release.pdf: $(TOP)/www/copyright-release.pdf - cp $(TOP)/www/copyright-release.pdf . - -common.tcl: $(TOP)/www/common.tcl - cp $(TOP)/www/common.tcl . - -conflict.html: $(TOP)/www/conflict.tcl - tclsh $(TOP)/www/conflict.tcl >conflict.html - -datatypes.html: $(TOP)/www/datatypes.tcl - tclsh $(TOP)/www/datatypes.tcl >datatypes.html - -datatype3.html: $(TOP)/www/datatype3.tcl - tclsh $(TOP)/www/datatype3.tcl >datatype3.html - -docs.html: $(TOP)/www/docs.tcl - tclsh $(TOP)/www/docs.tcl >docs.html - -download.html: $(TOP)/www/download.tcl - mkdir -p doc - tclsh $(TOP)/www/download.tcl >download.html - -faq.html: $(TOP)/www/faq.tcl - tclsh $(TOP)/www/faq.tcl >faq.html - -fileformat.html: $(TOP)/www/fileformat.tcl - tclsh $(TOP)/www/fileformat.tcl >fileformat.html - -formatchng.html: $(TOP)/www/formatchng.tcl - tclsh $(TOP)/www/formatchng.tcl >formatchng.html - -index.html: $(TOP)/www/index.tcl last_change - tclsh $(TOP)/www/index.tcl >index.html - -lang.html: $(TOP)/www/lang.tcl - tclsh $(TOP)/www/lang.tcl >lang.html - -pragma.html: $(TOP)/www/pragma.tcl - tclsh $(TOP)/www/pragma.tcl >pragma.html - -lockingv3.html: $(TOP)/www/lockingv3.tcl - tclsh $(TOP)/www/lockingv3.tcl >lockingv3.html - -oldnews.html: $(TOP)/www/oldnews.tcl - tclsh $(TOP)/www/oldnews.tcl >oldnews.html - -omitted.html: $(TOP)/www/omitted.tcl - tclsh $(TOP)/www/omitted.tcl >omitted.html - -opcode.html: $(TOP)/www/opcode.tcl $(TOP)/src/vdbe.c - tclsh $(TOP)/www/opcode.tcl $(TOP)/src/vdbe.c >opcode.html - -mingw.html: $(TOP)/www/mingw.tcl - tclsh $(TOP)/www/mingw.tcl >mingw.html - -nulls.html: $(TOP)/www/nulls.tcl - tclsh $(TOP)/www/nulls.tcl >nulls.html - -quickstart.html: $(TOP)/www/quickstart.tcl - tclsh $(TOP)/www/quickstart.tcl >quickstart.html - -speed.html: $(TOP)/www/speed.tcl - tclsh $(TOP)/www/speed.tcl >speed.html - -sqlite.gif: $(TOP)/art/SQLite.gif - cp $(TOP)/art/SQLite.gif sqlite.gif - -sqlite.html: $(TOP)/www/sqlite.tcl - tclsh $(TOP)/www/sqlite.tcl >sqlite.html - -support.html: $(TOP)/www/support.tcl - tclsh $(TOP)/www/support.tcl >support.html - -tclsqlite.html: $(TOP)/www/tclsqlite.tcl - tclsh $(TOP)/www/tclsqlite.tcl >tclsqlite.html - -vdbe.html: $(TOP)/www/vdbe.tcl - tclsh $(TOP)/www/vdbe.tcl >vdbe.html - -version3.html: $(TOP)/www/version3.tcl - tclsh $(TOP)/www/version3.tcl >version3.html - - -# Files to be published on the website. -# -DOC = \ - arch.html \ - arch.png \ - autoinc.html \ - c_interface.html \ - capi3.html \ - capi3ref.html \ - changes.html \ - compile.html \ - copyright.html \ - copyright-release.html \ - copyright-release.pdf \ - conflict.html \ - datatypes.html \ - datatype3.html \ - docs.html \ - download.html \ - faq.html \ - fileformat.html \ - formatchng.html \ - index.html \ - lang.html \ - lockingv3.html \ - mingw.html \ - nulls.html \ - oldnews.html \ - omitted.html \ - opcode.html \ - pragma.html \ - quickstart.html \ - speed.html \ - sqlite.gif \ - sqlite.html \ - support.html \ - tclsqlite.html \ - vdbe.html \ - version3.html - -doc: common.tcl $(DOC) - mkdir -p doc - mv $(DOC) doc - -install: sqlite3 libsqlite3.la sqlite3.h ${HAVE_TCL:1=tcl_install} - $(INSTALL) -d $(DESTDIR)$(libdir) - $(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir) - $(INSTALL) -d $(DESTDIR)$(exec_prefix)/bin - $(LTINSTALL) sqlite3 $(DESTDIR)$(exec_prefix)/bin - $(INSTALL) -d $(DESTDIR)$(prefix)/include - $(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(prefix)/include - $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig; - $(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(libdir)/pkgconfig; - -tcl_install: libtclsqlite3.la - tclsh $(TOP)/tclinstaller.tcl $(VERSION) - -clean: - rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la - rm -f sqlite3.h opcodes.* - rm -rf .libs .deps - rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz - rm -f mkkeywordhash$(BEXE) keywordhash.h - rm -f $(PUBLISH) - rm -f *.da *.bb *.bbg gmon.out - rm -f testfixture$(TEXE) test.db - rm -rf doc - rm -f common.tcl - rm -f sqlite3.dll sqlite3.lib - -# -# Windows section; all this funky .dll stuff ;-) -# -dll: sqlite3.dll - -REAL_LIBOBJ = $(LIBOBJ:%.lo=.libs/%.o) - -sqlite3.dll: $(LIBOBJ) $(TOP)/sqlite3.def - dllwrap --dllname sqlite3.dll --def $(TOP)/sqlite3.def $(REAL_LIBOBJ) - strip sqlite3.dll - -#target for dll import libraries -implib: sqlite3.lib - -#make Borland C++ and/or Microsoft VC import library for the dll -# ignore any errors (usually due to missing programs) -sqlite3.lib: sqlite3.dll - -implib -a sqlite3.lib sqlite3.dll - -lib /machine:i386 /def:$(TOP)/sqlite3.def - -distclean: clean - rm -f config.log config.status libtool Makefile config.h diff --git a/sqlite/VERSION b/sqlite/VERSION deleted file mode 100644 index ef538c2..0000000 --- a/sqlite/VERSION +++ /dev/null @@ -1 +0,0 @@ -3.1.2 diff --git a/sqlite/configure b/sqlite/configure deleted file mode 100755 index ca692ae..0000000 --- a/sqlite/configure +++ /dev/null @@ -1,21326 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59. -# -# Copyright (C) 2003 Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi -DUALCASE=1; export DUALCASE # for MKS sh - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - - - -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` - ;; -esac - -echo=${ECHO-echo} -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then - # Yippee, $echo works! - : -else - # Restart under the correct shell. - exec $SHELL "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat </dev/null && - echo_test_string="`eval $cmd`" && - (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null - then - break - fi - done -fi - -if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : -else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$echo" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - echo='print -r' - elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} - else - # Try using printf. - echo='printf %s\n' - if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - echo="$CONFIG_SHELL $0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$CONFIG_SHELL $0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do - if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "$0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} - else - # Oops. We lost completely, so just stick with echo. - echo=echo - fi - fi - fi - fi -fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -ECHO=$echo -if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then - ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" -fi - - - - -tagnames=${tagnames+${tagnames},}CXX - -tagnames=${tagnames+${tagnames},}F77 - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -exec 6>&1 - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_config_libobj_dir=. -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} - -# Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= - -ac_unique_file="src/sqlite.h.in" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_STAT_H -# include -#endif -#if STDC_HEADERS -# include -# include -#else -# if HAVE_STDLIB_H -# include -# endif -#endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H -# include -# endif -# include -#endif -#if HAVE_STRINGS_H -# include -#endif -#if HAVE_INTTYPES_H -# include -#else -# if HAVE_STDINT_H -# include -# endif -#endif -#if HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CPP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA program_prefix VERSION VERSION_NUMBER RELEASE BUILD_CC BUILD_CFLAGS BUILD_LIBS TARGET_CC TARGET_CFLAGS TARGET_LINK TARGET_LFLAGS TARGET_RANLIB TARGET_AR THREADSAFE TARGET_THREAD_LIB ALLOWRELEASE TEMP_STORE BUILD_EXEEXT OS_UNIX OS_WIN TARGET_EXEEXT TARGET_LIBS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIBS TCL_INCLUDE_SPEC TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC HAVE_TCL TARGET_READLINE_LIBS TARGET_READLINE_INC TARGET_HAVE_READLINE TARGET_DEBUG LIBOBJS LTLIBOBJS' -ac_subst_files='' - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -ac_prev= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_option in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "enable_$ac_feature='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "with_$ac_package='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } - fi -fi -(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || - { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 - { (exit 1); exit 1; }; } -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias -ac_env_CC_set=${CC+set} -ac_env_CC_value=$CC -ac_cv_env_CC_set=${CC+set} -ac_cv_env_CC_value=$CC -ac_env_CFLAGS_set=${CFLAGS+set} -ac_env_CFLAGS_value=$CFLAGS -ac_cv_env_CFLAGS_set=${CFLAGS+set} -ac_cv_env_CFLAGS_value=$CFLAGS -ac_env_LDFLAGS_set=${LDFLAGS+set} -ac_env_LDFLAGS_value=$LDFLAGS -ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -ac_cv_env_LDFLAGS_value=$LDFLAGS -ac_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_env_CPPFLAGS_value=$CPPFLAGS -ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_cv_env_CPPFLAGS_value=$CPPFLAGS -ac_env_CPP_set=${CPP+set} -ac_env_CPP_value=$CPP -ac_cv_env_CPP_set=${CPP+set} -ac_cv_env_CPP_value=$CPP -ac_env_CXX_set=${CXX+set} -ac_env_CXX_value=$CXX -ac_cv_env_CXX_set=${CXX+set} -ac_cv_env_CXX_value=$CXX -ac_env_CXXFLAGS_set=${CXXFLAGS+set} -ac_env_CXXFLAGS_value=$CXXFLAGS -ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} -ac_cv_env_CXXFLAGS_value=$CXXFLAGS -ac_env_CXXCPP_set=${CXXCPP+set} -ac_env_CXXCPP_value=$CXXCPP -ac_cv_env_CXXCPP_set=${CXXCPP+set} -ac_cv_env_CXXCPP_value=$CXXCPP -ac_env_F77_set=${F77+set} -ac_env_F77_value=$F77 -ac_cv_env_F77_set=${F77+set} -ac_cv_env_F77_value=$F77 -ac_env_FFLAGS_set=${FFLAGS+set} -ac_env_FFLAGS_value=$FFLAGS -ac_cv_env_FFLAGS_set=${FFLAGS+set} -ac_cv_env_FFLAGS_value=$FFLAGS - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -_ACEOF - - cat <<_ACEOF -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data [PREFIX/share] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] -_ACEOF - - cat <<\_ACEOF - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - - cat <<\_ACEOF - -Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-shared[=PKGS] - build shared libraries [default=yes] - --enable-static[=PKGS] - build static libraries [default=yes] - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) - --enable-threadsafe Support threadsafe operation - --enable-releasemode Support libtool link to release mode - --enable-tempstore Use an in-ram database for temporary tables (never,no,yes,always) - --disable-tcl do not build TCL extension - --enable-debug enable debugging & verbose explain - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-pic try to use only PIC/non-PIC objects [default=use - both] - --with-tags[=TAGS] - include additional configurations [automatic] - --with-hints=FILE Read configuration options from FILE - --with-tcl=DIR directory containing tcl configuration (tclConfig.sh) - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have - headers in a nonstandard directory - CPP C preprocessor - CXX C++ compiler command - CXXFLAGS C++ compiler flags - CXXCPP C++ preprocessor - F77 Fortran 77 compiler command - FFLAGS Fortran 77 compiler flags - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -_ACEOF -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - ac_popdir=`pwd` - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style configure. - if test -f $ac_srcdir/configure.gnu; then - echo - $SHELL $ac_srcdir/configure.gnu --help=recursive - elif test -f $ac_srcdir/configure; then - echo - $SHELL $ac_srcdir/configure --help=recursive - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd $ac_popdir - done -fi - -test -n "$ac_init_help" && exit 0 -if $ac_init_version; then - cat <<\_ACEOF - -Copyright (C) 2003 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit 0 -fi -exec 5>config.log -cat >&5 <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by $as_me, which was -generated by GNU Autoconf 2.59. Invocation command line was - - $ $0 $@ - -_ACEOF -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -hostinfo = `(hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_sep= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - # Get rid of the leading space. - ac_sep=" " - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -{ - (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) - sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; - *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------- ## -## Output files. ## -## ------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - sed "/^$/d" confdefs.h | sort - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status - ' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val="\$ac_cv_env_${ac_var}_value" - eval ac_new_val="\$ac_env_${ac_var}_value" - case $ac_old_set,$ac_new_set in - set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - - - - - - - - - - - - - -# The following RCS revision string applies to configure.in -# $Revision: 1.30 $ - -######### -# Programs needed -# -# Check whether --enable-shared or --disable-shared was given. -if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_shared=yes -fi; - -# Check whether --enable-static or --disable-static was given. -if test "${enable_static+set}" = set; then - enableval="$enable_static" - p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_static=yes -fi; - -# Check whether --enable-fast-install or --disable-fast-install was given. -if test "${enable_fast_install+set}" = set; then - enableval="$enable_fast_install" - p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_fast_install=yes -fi; - -ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f $ac_dir/shtool; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 -echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} - { (exit 1); exit 1; }; } -fi -ac_config_guess="$SHELL $ac_aux_dir/config.guess" -ac_config_sub="$SHELL $ac_aux_dir/config.sub" -ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. - -# Make sure we can run config.sub. -$ac_config_sub sun4 >/dev/null 2>&1 || - { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 -echo "$as_me: error: cannot run $ac_config_sub" >&2;} - { (exit 1); exit 1; }; } - -echo "$as_me:$LINENO: checking build system type" >&5 -echo $ECHO_N "checking build system type... $ECHO_C" >&6 -if test "${ac_cv_build+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_build_alias=$build_alias -test -z "$ac_cv_build_alias" && - ac_cv_build_alias=`$ac_config_guess` -test -z "$ac_cv_build_alias" && - { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 -echo "$as_me: error: cannot guess build type; you must specify one" >&2;} - { (exit 1); exit 1; }; } -ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || - { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 -echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} - { (exit 1); exit 1; }; } - -fi -echo "$as_me:$LINENO: result: $ac_cv_build" >&5 -echo "${ECHO_T}$ac_cv_build" >&6 -build=$ac_cv_build -build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - - -echo "$as_me:$LINENO: checking host system type" >&5 -echo $ECHO_N "checking host system type... $ECHO_C" >&6 -if test "${ac_cv_host+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_host_alias=$host_alias -test -z "$ac_cv_host_alias" && - ac_cv_host_alias=$ac_cv_build_alias -ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || - { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 -echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} - { (exit 1); exit 1; }; } - -fi -echo "$as_me:$LINENO: result: $ac_cv_host" >&5 -echo "${ECHO_T}$ac_cv_host" >&6 -host=$ac_cv_host -host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CC" && break -done - - CC=$ac_ct_CC -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 - (eval $ac_link_default) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Find the output, starting from the most likely. This scheme is -# not robust to junk in `.', hence go to wildcards (a.*) only as a last -# resort. - -# Be careful to initialize this variable, since it used to be cached. -# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -ac_cv_exeext= -# b.out is created by i960 compilers. -for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) - ;; - conftest.$ac_ext ) - # This is the source file. - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool, - # but it would be cool to find out if it's true. Does anybody - # maintain Libtool? --akim. - export ac_cv_exeext - break;; - * ) - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6 - -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - -rm -f a.out a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6 - -echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6 - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6 -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_cc_g=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 -echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_stdc=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std1 is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std1. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX 10.20 and later -Ae -# HP-UX older versions -Aa -D_HPUX_SOURCE -# SVR4 -Xc -D__EXTENSIONS__ -for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_stdc=$ac_arg -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext -done -rm -f conftest.$ac_ext conftest.$ac_objext -CC=$ac_save_CC - -fi - -case "x$ac_cv_prog_cc_stdc" in - x|xno) - echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6 ;; - *) - echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 - CC="$CC $ac_cv_prog_cc_stdc" ;; -esac - -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 -echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 -if test "${lt_cv_path_SED+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && break - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -SED=$lt_cv_path_SED - -fi - -echo "$as_me:$LINENO: result: $SED" >&5 -echo "${ECHO_T}$SED" >&6 - -echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6 -if test "${ac_cv_prog_egrep+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if echo a | (grep -E '(a|b)') >/dev/null 2>&1 - then ac_cv_prog_egrep='grep -E' - else ac_cv_prog_egrep='egrep' - fi -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 -echo "${ECHO_T}$ac_cv_prog_egrep" >&6 - EGREP=$ac_cv_prog_egrep - - - -# Check whether --with-gnu-ld or --without-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then - withval="$with_gnu_ld" - test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi; -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - echo "$as_me:$LINENO: checking for ld used by $CC" >&5 -echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - echo "$as_me:$LINENO: checking for GNU ld" >&5 -echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 -else - echo "$as_me:$LINENO: checking for non-GNU ld" >&5 -echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 -fi -if test "${lt_cv_path_LD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &5 -echo "${ECHO_T}$LD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi -test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 -echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} - { (exit 1); exit 1; }; } -echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 -echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 -if test "${lt_cv_prog_gnu_ld+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # I'd rather use --version here, but apparently some GNU ld's only accept -v. -case `$LD -v 2>&1 &5 -echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 -with_gnu_ld=$lt_cv_prog_gnu_ld - - -echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 -echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 -if test "${lt_cv_ld_reload_flag+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_ld_reload_flag='-r' -fi -echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 -echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' - -echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 -echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 -if test "${lt_cv_path_NM+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/${ac_tool_prefix}nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - esac - fi - done - IFS="$lt_save_ifs" - test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm -fi -fi -echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 -echo "${ECHO_T}$lt_cv_path_NM" >&6 -NM="$lt_cv_path_NM" - -echo "$as_me:$LINENO: checking whether ln -s works" >&5 -echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else - echo "$as_me:$LINENO: result: no, using $LN_S" >&5 -echo "${ECHO_T}no, using $LN_S" >&6 -fi - -echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 -echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 -if test "${lt_cv_deplibs_check_method+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix4* | aix5*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi4*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # win32_libid shell function, so use a weaker test based on 'objdump'. - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | kfreebsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case "$host_cpu" in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux*) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -nto-qnx*) - lt_cv_deplibs_check_method=unknown - ;; - -openbsd*) - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' - else - lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -sco3.2v5*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; -esac - -fi -echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 -echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Check whether --enable-libtool-lock or --disable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then - enableval="$enable_libtool_lock" - -fi; -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '#line 3058 "configure"' > conftest.$ac_ext - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - case "`/usr/bin/file conftest.o`" in - *32-bit*) - case $host in - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 -echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 -if test "${lt_cv_cc_needs_belf+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - lt_cv_cc_needs_belf=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -lt_cv_cc_needs_belf=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 -echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; - -esac - -need_locks="$enable_libtool_lock" - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6 -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_header_stdc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_header_stdc=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - exit(2); - exit (0); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6 -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_Header=no" -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - -for ac_header in dlfcn.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -n "$ac_tool_prefix"; then - for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - echo "$as_me:$LINENO: result: $CXX" >&5 -echo "${ECHO_T}$CXX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 -echo "${ECHO_T}$ac_ct_CXX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CXX" && break -done -test -n "$ac_ct_CXX" || ac_ct_CXX="g++" - - CXX=$ac_ct_CXX -fi - - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C++ compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 -GXX=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -CXXFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 -echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cxx_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cxx_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_cxx_g=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 -echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 -if test -z "$CXXCPP"; then - if test "${ac_cv_prog_CXXCPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CXXCPP needs to be expanded - for CXXCPP in "$CXX -E" "/lib/cpp" - do - ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CXXCPP=$CXXCPP - -fi - CXXCPP=$ac_cv_prog_CXXCPP -else - ac_cv_prog_CXXCPP=$CXXCPP -fi -echo "$as_me:$LINENO: result: $CXXCPP" >&5 -echo "${ECHO_T}$CXXCPP" >&6 -ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -ac_ext=f -ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' -ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_f77_compiler_gnu -if test -n "$ac_tool_prefix"; then - for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_F77+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$F77"; then - ac_cv_prog_F77="$F77" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_F77="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -F77=$ac_cv_prog_F77 -if test -n "$F77"; then - echo "$as_me:$LINENO: result: $F77" >&5 -echo "${ECHO_T}$F77" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$F77" && break - done -fi -if test -z "$F77"; then - ac_ct_F77=$F77 - for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_F77+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_F77"; then - ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_F77="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_F77=$ac_cv_prog_ac_ct_F77 -if test -n "$ac_ct_F77"; then - echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 -echo "${ECHO_T}$ac_ct_F77" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_F77" && break -done - - F77=$ac_ct_F77 -fi - - -# Provide some information about the compiler. -echo "$as_me:4521:" \ - "checking for Fortran 77 compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -rm -f a.out - -# If we don't use `.F' as extension, the preprocessor is not run on the -# input file. (Note that this only needs to work for GNU compilers.) -ac_save_ext=$ac_ext -ac_ext=F -echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6 -if test "${ac_cv_f77_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF - program main -#ifndef __GNUC__ - choke me -#endif - - end -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_f77_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6 -ac_ext=$ac_save_ext -ac_test_FFLAGS=${FFLAGS+set} -ac_save_FFLAGS=$FFLAGS -FFLAGS= -echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 -echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_f77_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - FFLAGS=-g -cat >conftest.$ac_ext <<_ACEOF - program main - - end -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_f77_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_f77_g=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 -echo "${ECHO_T}$ac_cv_prog_f77_g" >&6 -if test "$ac_test_FFLAGS" = set; then - FFLAGS=$ac_save_FFLAGS -elif test $ac_cv_prog_f77_g = yes; then - if test "x$ac_cv_f77_compiler_gnu" = xyes; then - FFLAGS="-g -O2" - else - FFLAGS="-g" - fi -else - if test "x$ac_cv_f77_compiler_gnu" = xyes; then - FFLAGS="-O2" - else - FFLAGS= - fi -fi - -G77=`test $ac_compiler_gnu = yes && echo yes` -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! - -# find the maximum length of command line arguments -echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 -echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6 -if test "${lt_cv_sys_max_cmd_len+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - i=0 - testring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - *) - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while (test "X"`$CONFIG_SHELL $0 --fallback-echo "X$testring" 2>/dev/null` \ - = "XX$testring") >/dev/null 2>&1 && - new_result=`expr "X$testring" : ".*" 2>&1` && - lt_cv_sys_max_cmd_len=$new_result && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - testring=$testring$testring - done - testring= - # Add a significant safety factor because C++ compilers can tack on massive - # amounts of additional arguments before passing them to the linker. - # It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - ;; - esac - -fi - -if test -n $lt_cv_sys_max_cmd_len ; then - echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 -echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6 -else - echo "$as_me:$LINENO: result: none" >&5 -echo "${ECHO_T}none" >&6 -fi - - - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 -echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6 -if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Transform the above into a raw symbol and a C symbol. -symxfrm='\1 \2\3 \3' - -# Transform an extracted symbol line into a proper C declaration -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32*) - symcode='[ABCDGISTW]' - ;; -hpux*) # Its linker distinguishes data from code symbols - if test "$host_cpu" = ia64; then - symcode='[ABCDEGRST]' - fi - lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris* | sysv5*) - symcode='[BDRT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[ABCDGIRSTW]' ;; -esac - -# Try without a prefix undercore, then with it. -for ac_symprfx in "" "_"; do - - # Write the raw and C identifiers. - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Now try to grab the symbols. - nlist=conftest.nm - if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 - (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if grep ' nm_test_var$' "$nlist" >/dev/null; then - if grep ' nm_test_func$' "$nlist" >/dev/null; then - cat < conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' - - cat <> conftest.$ac_ext -#if defined (__STDC__) && __STDC__ -# define lt_ptr_t void * -#else -# define lt_ptr_t char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr_t address; -} -lt_preloaded_symbols[] = -{ -EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext - cat <<\EOF >> conftest.$ac_ext - {0, (lt_ptr_t) 0} -}; - -#ifdef __cplusplus -} -#endif -EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -f conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - echo "$as_me:$LINENO: result: failed" >&5 -echo "${ECHO_T}failed" >&6 -else - echo "$as_me:$LINENO: result: ok" >&5 -echo "${ECHO_T}ok" >&6 -fi - -echo "$as_me:$LINENO: checking for objdir" >&5 -echo $ECHO_N "checking for objdir... $ECHO_C" >&6 -if test "${lt_cv_objdir+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null -fi -echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 -echo "${ECHO_T}$lt_cv_objdir" >&6 -objdir=$lt_cv_objdir - - - - - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e s/^X//' -sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Constants: -rm="rm -f" - -# Global variables: -default_ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except M$VC, -# which needs '.lib'). -libext=a -ltmain="$ac_aux_dir/ltmain.sh" -ofile="$default_ofile" -with_gnu_ld="$lt_cv_prog_gnu_ld" - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="${ac_tool_prefix}ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - echo "$as_me:$LINENO: result: $AR" >&5 -echo "${ECHO_T}$AR" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_AR"; then - ac_ct_AR=$AR - # Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false" -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 -echo "${ECHO_T}$ac_ct_AR" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - AR=$ac_ct_AR -else - AR="$ac_cv_prog_AR" -fi - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - RANLIB=$ac_ct_RANLIB -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - echo "$as_me:$LINENO: result: $STRIP" >&5 -echo "${ECHO_T}$STRIP" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 -echo "${ECHO_T}$ac_ct_STRIP" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - STRIP=$ac_ct_STRIP -else - STRIP="$ac_cv_prog_STRIP" -fi - - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -test -z "$AS" && AS=as -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$DLLTOOL" && DLLTOOL=dlltool -test -z "$LD" && LD=ld -test -z "$LN_S" && LN_S="ln -s" -test -z "$MAGIC_CMD" && MAGIC_CMD=file -test -z "$NM" && NM=nm -test -z "$SED" && SED=sed -test -z "$OBJDUMP" && OBJDUMP=objdump -test -z "$RANLIB" && RANLIB=: -test -z "$STRIP" && STRIP=: -test -z "$ac_objext" && ac_objext=o - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" - ;; - *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - -# Only perform the check for file, if the check method requires it -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 -echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 -if test "${lt_cv_path_MAGIC_CMD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 -echo "${ECHO_T}$MAGIC_CMD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - echo "$as_me:$LINENO: checking for file" >&5 -echo $ECHO_N "checking for file... $ECHO_C" >&6 -if test "${lt_cv_path_MAGIC_CMD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 -echo "${ECHO_T}$MAGIC_CMD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -enable_dlopen=no -enable_win32_dll=no - -# Check whether --enable-libtool-lock or --disable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then - enableval="$enable_libtool_lock" - -fi; -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - - -# Check whether --with-pic or --without-pic was given. -if test "${with_pic+set}" = set; then - withval="$with_pic" - pic_mode="$withval" -else - pic_mode=default -fi; -test -z "$pic_mode" && pic_mode=default - -# Use C for the default configuration in the libtool script -tagname= -lt_save_CC="$CC" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -objext=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}\n' - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# -# Check for any special shared library compilation flags. -# -lt_prog_cc_shlib= -if test "$GCC" = no; then - case $host_os in - sco3.2v5*) - lt_prog_cc_shlib='-belf' - ;; - esac -fi -if test -n "$lt_prog_cc_shlib"; then - { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&5 -echo "$as_me: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&2;} - if echo "$old_CC $old_CFLAGS " | grep "[ ]$lt_prog_cc_shlib[ ]" >/dev/null; then : - else - { echo "$as_me:$LINENO: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5 -echo "$as_me: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;} - lt_cv_prog_cc_can_build_shared=no - fi -fi - - -# -# Check to make sure the static flag actually works. -# -echo "$as_me:$LINENO: checking if $compiler static flag $lt_prog_compiler_static works" >&5 -echo $ECHO_N "checking if $compiler static flag $lt_prog_compiler_static works... $ECHO_C" >&6 -if test "${lt_prog_compiler_static_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_prog_compiler_static" - printf "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - else - lt_prog_compiler_static_works=yes - fi - fi - $rm conftest* - LDFLAGS="$save_LDFLAGS" - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 -echo "${ECHO_T}$lt_prog_compiler_static_works" >&6 - -if test x"$lt_prog_compiler_static_works" = xyes; then - : -else - lt_prog_compiler_static= -fi - - - - -lt_prog_compiler_no_builtin_flag= - -if test "$GCC" = yes; then - lt_prog_compiler_no_builtin_flag=' -fno-builtin' - - -echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:5555: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:5559: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 - -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then - lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" -else - : -fi - -fi - -lt_prog_compiler_wl= -lt_prog_compiler_pic= -lt_prog_compiler_static= - -echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 -echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 - - if test "$GCC" = yes; then - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_static='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - fi - ;; - - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' - ;; - - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared=no - enable_shared=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic=-Kconform_pic - fi - ;; - - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case "$host_cpu" in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - ;; - - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - else - lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case "$host_cpu" in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static='-non_shared' - ;; - - newsos6) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - linux*) - case $CC in - icc* | ecc*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-static' - ;; - ccc*) - lt_prog_compiler_wl='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - esac - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - - sco3.2v5*) - lt_prog_compiler_pic='-Kpic' - lt_prog_compiler_static='-dn' - ;; - - solaris*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sunos4*) - lt_prog_compiler_wl='-Qoption ld ' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic='-Kconform_pic' - lt_prog_compiler_static='-Bstatic' - fi - ;; - - uts4*) - lt_prog_compiler_pic='-pic' - lt_prog_compiler_static='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic" >&6 - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic"; then - -echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6 -if test "${lt_prog_compiler_pic_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_pic_works=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:5788: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:5792: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then - lt_prog_compiler_pic_works=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6 - -if test x"$lt_prog_compiler_pic_works" = xyes; then - case $lt_prog_compiler_pic in - "" | " "*) ;; - *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; - esac -else - lt_prog_compiler_pic= - lt_prog_compiler_can_build_shared=no -fi - -fi -case "$host_os" in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic= - ;; - *) - lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" - ;; -esac - -echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 -echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_c_o+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_c_o=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:5848: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:5852: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s out/conftest.err; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6 - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 -echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$as_me:$LINENO: result: $hard_links" >&5 -echo "${ECHO_T}$hard_links" >&6 - if test "$hard_links" = no; then - { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - -echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 - - runpath_var= - allow_undefined_flag= - enable_shared_with_static_runtimes=no - archive_cmds= - archive_expsym_cmds= - old_archive_From_new_cmds= - old_archive_from_expsyms_cmds= - export_dynamic_flag_spec= - whole_archive_flag_spec= - thread_safe_flag_spec= - hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld= - hardcode_libdir_separator= - hardcode_direct=no - hardcode_minus_L=no - hardcode_shlibpath_var=unsupported - link_all_deplibs=unknown - hardcode_automatic=no - module_cmds= - module_expsym_cmds= - always_export_symbols=no - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms="_GLOBAL_OFFSET_TABLE_" - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - ld_shlibs=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - fi - ;; - - amigaos*) - archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can't use - # them. - ld_shlibs=no - ;; - - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - allow_undefined_flag=unsupported - always_export_symbols=no - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - ld_shlibs=no - fi - ;; - - netbsd* | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - linux*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_cmds="$tmp_archive_cmds" - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - if test $supports_anon_versioning = yes; then - archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ -cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ -$echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - else - archive_expsym_cmds="$tmp_archive_cmds" - fi - else - ld_shlibs=no - fi - ;; - - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_direct=yes - hardcode_libdir_separator=':' - link_all_deplibs=yes - - if test "$GCC" = yes; then - case $host_os in aix4.012|aix4.012.*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct=yes - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - esac - shared_flag='-shared' - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols=yes - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec=' ' - archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no - ;; - - bsdi4*) - export_dynamic_flag_spec=-rdynamic - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_From_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - enable_shared_with_static_runtimes=yes - ;; - - darwin* | rhapsody*) - if test "$GXX" = yes ; then - archive_cmds_need_lc=no - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag='-flat_namespace -undefined suppress' - ;; - 10.*) - allow_undefined_flag='-undefined dynamic_lookup' - ;; - esac - fi - ;; - esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_cmds='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - archive_cmds='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - module_cmds='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - whole_archive_flag_spec='-all_load $convenience' - link_all_deplibs=yes - else - ld_shlibs=no - fi - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - freebsd1*) - ld_shlibs=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu) - archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' - ;; - - hpux10* | hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' - ;; - *) - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld='+b $libdir' - hardcode_libdir_separator=: - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - ia64*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=no - hardcode_shlibpath_var=no - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - *) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - export_dynamic_flag_spec='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_ld='-rpath $libdir' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - link_all_deplibs=yes - ;; - - netbsd* | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - openbsd*) - hardcode_direct=yes - hardcode_shlibpath_var=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - ;; - - sco3.2v5*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - no_undefined_flag=' -z text' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' - else - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=no - hardcode_shlibpath_var=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag='${wl}-z ${wl}text' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv5*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec= - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $ld_shlibs" >&5 -echo "${ECHO_T}$ld_shlibs" >&6 -test "$ld_shlibs" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 -echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 - (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - then - archive_cmds_need_lc=no - else - archive_cmds_need_lc=yes - fi - allow_undefined_flag=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 -echo "${ECHO_T}$archive_cmds_need_lc" >&6 - ;; - esac - fi - ;; -esac - -echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 -echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi4*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext='$(test .$module = .yes && echo .so || echo .dylib)' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.01* | freebsdelf3.01*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case "$host_cpu" in - ia64*) - shrext='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf` - sys_lib_dlsearch_path_spec="/lib /usr/lib $ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - need_version=yes - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$as_me:$LINENO: result: $dynamic_linker" >&5 -echo "${ECHO_T}$dynamic_linker" >&6 -test "$dynamic_linker" = no && can_build_shared=no - -echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 -echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || \ - test -n "$runpath_var " || \ - test "X$hardcode_automatic"="Xyes" ; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -echo "$as_me:$LINENO: result: $hardcode_action" >&5 -echo "${ECHO_T}$hardcode_action" >&6 - -if test "$hardcode_action" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - echo "$as_me:$LINENO: checking for shl_load" >&5 -echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 -if test "${ac_cv_func_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define shl_load to an innocuous variant, in case declares shl_load. - For example, HP-UX 11i declares gettimeofday. */ -#define shl_load innocuous_shl_load - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char shl_load (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef shl_load - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -char (*f) () = shl_load; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != shl_load; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 -echo "${ECHO_T}$ac_cv_func_shl_load" >&6 -if test $ac_cv_func_shl_load = yes; then - lt_cv_dlopen="shl_load" -else - echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -int -main () -{ -shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 -if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - echo "$as_me:$LINENO: checking for dlopen" >&5 -echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 -if test "${ac_cv_func_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define dlopen to an innocuous variant, in case declares dlopen. - For example, HP-UX 11i declares gettimeofday. */ -#define dlopen innocuous_dlopen - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char dlopen (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef dlopen - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -char (*f) () = dlopen; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != dlopen; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 -echo "${ECHO_T}$ac_cv_func_dlopen" >&6 -if test $ac_cv_func_dlopen = yes; then - lt_cv_dlopen="dlopen" -else - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 -echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 -if test "${ac_cv_lib_svld_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_svld_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_svld_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 -if test $ac_cv_lib_svld_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 -echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_dld_link+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dld_link (); -int -main () -{ -dld_link (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_dld_link=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_dld_link=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 -if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 -echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self" >&6 - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 -echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - -# Report which librarie types wil actually be built -echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 -echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $can_build_shared" >&5 -echo "${ECHO_T}$can_build_shared" >&6 - -echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 -echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case "$host_os" in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - -aix4*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - darwin* | rhapsody*) - if test "$GCC" = yes; then - archive_cmds_need_lc=no - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag='-flat_namespace -undefined suppress' - ;; - 10.*) - allow_undefined_flag='-undefined dynamic_lookup' - ;; - esac - fi - ;; - esac - output_verbose_link_cmd='echo' - archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring' - module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - whole_archive_flag_spec='-all_load $convenience' - link_all_deplibs=yes - else - ld_shlibs=no - fi - ;; -esac -echo "$as_me:$LINENO: result: $enable_shared" >&5 -echo "${ECHO_T}$enable_shared" >&6 - -echo "$as_me:$LINENO: checking whether to build static libraries" >&5 -echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes -echo "$as_me:$LINENO: result: $enable_static" >&5 -echo "${ECHO_T}$enable_static" >&6 - -# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - compiler \ - CC \ - LD \ - lt_prog_compiler_wl \ - lt_prog_compiler_pic \ - lt_prog_compiler_static \ - lt_prog_compiler_no_builtin_flag \ - export_dynamic_flag_spec \ - thread_safe_flag_spec \ - whole_archive_flag_spec \ - enable_shared_with_static_runtimes \ - old_archive_cmds \ - old_archive_from_new_cmds \ - predep_objects \ - postdep_objects \ - predeps \ - postdeps \ - compiler_lib_search_path \ - archive_cmds \ - archive_expsym_cmds \ - postinstall_cmds \ - postuninstall_cmds \ - old_archive_from_expsyms_cmds \ - allow_undefined_flag \ - no_undefined_flag \ - export_symbols_cmds \ - hardcode_libdir_flag_spec \ - hardcode_libdir_flag_spec_ld \ - hardcode_libdir_separator \ - hardcode_automatic \ - module_cmds \ - module_expsym_cmds \ - lt_cv_prog_compiler_c_o \ - exclude_expsyms \ - include_expsyms; do - - case $var in - old_archive_cmds | \ - old_archive_from_new_cmds | \ - archive_cmds | \ - archive_expsym_cmds | \ - module_cmds | \ - module_expsym_cmds | \ - old_archive_from_expsyms_cmds | \ - export_symbols_cmds | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\$0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - -cfgfile="${ofile}T" - trap "$rm \"$cfgfile\"; exit 1" 1 2 15 - $rm -f "$cfgfile" - { echo "$as_me:$LINENO: creating $ofile" >&5 -echo "$as_me: creating $ofile" >&6;} - - cat <<__EOF__ >> "$cfgfile" -#! $SHELL - -# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. -# -# This file is part of GNU Libtool: -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="$SED -e s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi - -# The names of the tagged configurations supported by this script. -available_tags= - -# ### BEGIN LIBTOOL CONFIG - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU C compiler? -with_gcc=$GCC - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_LD - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext='$shrext' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Must we lock files when doing compilation ? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_predep_objects - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_postdep_objects - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_predeps - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_postdeps - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$hardcode_automatic - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# ### END LIBTOOL CONFIG - -__EOF__ - - - case $host_os in - aix3*) - cat <<\EOF >> "$cfgfile" - -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || \ - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - -# Check whether --with-tags or --without-tags was given. -if test "${with_tags+set}" = set; then - withval="$with_tags" - tagnames="$withval" -fi; - -if test -f "$ltmain" && test -n "$tagnames"; then - if test ! -f "${ofile}"; then - { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 -echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} - fi - - if test -z "$LTCC"; then - eval "`$SHELL ${ofile} --config | grep '^LTCC='`" - if test -z "$LTCC"; then - { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 -echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} - else - { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 -echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} - fi - fi - - # Extract list of available tagged configurations in $ofile. - # Note that this assumes the entire list is on one line. - available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` - - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for tagname in $tagnames; do - IFS="$lt_save_ifs" - # Check whether tagname contains only valid characters - case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in - "") ;; - *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 -echo "$as_me: error: invalid tag name: $tagname" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null - then - { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 -echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} - { (exit 1); exit 1; }; } - fi - - # Update the list of available tags. - if test -n "$tagname"; then - echo appending configuration tag \"$tagname\" to $ofile - - case $tagname in - CXX) - if test -n "$CXX" && test "X$CXX" != "Xno"; then - ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - - -archive_cmds_need_lc_CXX=no -allow_undefined_flag_CXX= -always_export_symbols_CXX=no -archive_expsym_cmds_CXX= -export_dynamic_flag_spec_CXX= -hardcode_direct_CXX=no -hardcode_libdir_flag_spec_CXX= -hardcode_libdir_flag_spec_ld_CXX= -hardcode_libdir_separator_CXX= -hardcode_minus_L_CXX=no -hardcode_automatic_CXX=no -module_cmds_CXX= -module_expsym_cmds_CXX= -link_all_deplibs_CXX=unknown -old_archive_cmds_CXX=$old_archive_cmds -no_undefined_flag_CXX= -whole_archive_flag_spec_CXX= -enable_shared_with_static_runtimes_CXX=no - -# Dependencies to place before and after the object being linked: -predep_objects_CXX= -postdep_objects_CXX= -predeps_CXX= -postdeps_CXX= -compiler_lib_search_path_CXX= - -# Source file extension for C++ test sources. -ac_ext=cc - -# Object file extension for compiled C++ test sources. -objext=o -objext_CXX=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(int, char *) { return(0); }\n' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_LD=$LD -lt_save_GCC=$GCC -GCC=$GXX -lt_save_with_gnu_ld=$with_gnu_ld -lt_save_path_LD=$lt_cv_path_LD -if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx -else - unset lt_cv_prog_gnu_ld -fi -if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX -else - unset lt_cv_path_LD -fi -test -z "${LDCXX+set}" || LD=$LDCXX -CC=${CXX-"c++"} -compiler=$CC -compiler_CXX=$CC -cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` - -# We don't want -fno-exception wen compiling C++ code, so set the -# no_builtin_flag separately -if test "$GXX" = yes; then - lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' -else - lt_prog_compiler_no_builtin_flag_CXX= -fi - -if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - -# Check whether --with-gnu-ld or --without-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then - withval="$with_gnu_ld" - test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi; -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - echo "$as_me:$LINENO: checking for ld used by $CC" >&5 -echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - echo "$as_me:$LINENO: checking for GNU ld" >&5 -echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 -else - echo "$as_me:$LINENO: checking for non-GNU ld" >&5 -echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 -fi -if test "${lt_cv_path_LD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &5 -echo "${ECHO_T}$LD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi -test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 -echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} - { (exit 1); exit 1; }; } -echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 -echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 -if test "${lt_cv_prog_gnu_ld+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # I'd rather use --version here, but apparently some GNU ld's only accept -v. -case `$LD -v 2>&1 &5 -echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ - grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec_CXX= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - -else - GXX=no - with_gnu_ld=no - wlarc= -fi - -# PORTME: fill in a description of your system's C++ link characteristics -echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 -ld_shlibs_CXX=yes -case $host_os in - aix3*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds_CXX='' - hardcode_direct_CXX=yes - hardcode_libdir_separator_CXX=':' - link_all_deplibs_CXX=yes - - if test "$GXX" = yes; then - case $host_os in aix4.012|aix4.012.*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct_CXX=yes - else - # We have old collect2 - hardcode_direct_CXX=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L_CXX=yes - hardcode_libdir_flag_spec_CXX='-L$libdir' - hardcode_libdir_separator_CXX= - fi - esac - shared_flag='-shared' - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols_CXX=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag_CXX='-berok' - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" - - archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag_CXX="-z nodefs" - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag_CXX=' ${wl}-bernotok' - allow_undefined_flag_CXX=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_CXX=yes - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_CXX=' ' - archive_cmds_need_lc_CXX=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec_CXX='-L$libdir' - allow_undefined_flag_CXX=unsupported - always_export_symbols_CXX=no - enable_shared_with_static_runtimes_CXX=yes - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - ld_shlibs_CXX=no - fi - ;; - - darwin* | rhapsody*) - if test "$GXX" = yes; then - archive_cmds_need_lc_CXX=no - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag_CXX='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag_CXX='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag_CXX='-flat_namespace -undefined suppress' - ;; - 10.*) - allow_undefined_flag_CXX='-undefined dynamic_lookup' - ;; - esac - fi - ;; - esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - archive_cmds_CXX='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - module_cmds_CXX='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes - hardcode_shlibpath_var_CXX=unsupported - whole_archive_flag_spec_CXX='-all_load $convenience' - link_all_deplibs_CXX=yes - else - ld_shlibs_CXX=no - fi - ;; - - dgux*) - case $cc_basename in - ec++) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - ghcx) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - freebsd12*) - # C++ shared libraries reported to be fairly broken before switch to ELF - ld_shlibs_CXX=no - ;; - freebsd-elf*) - archive_cmds_need_lc_CXX=no - ;; - freebsd* | kfreebsd*-gnu) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - ld_shlibs_CXX=yes - ;; - gnu*) - ;; - hpux9*) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_CXX=: - export_dynamic_flag_spec_CXX='${wl}-E' - hardcode_direct_CXX=yes - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aCC) - archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | egrep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes; then - archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_CXX='+b $libdir' - hardcode_libdir_separator_CXX=: - ;; - ia64*) - hardcode_libdir_flag_spec_CXX='-L$libdir' - ;; - *) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_CXX=: - export_dynamic_flag_spec_CXX='${wl}-E' - ;; - esac - fi - case "$host_cpu" in - hppa*64*) - hardcode_direct_CXX=no - hardcode_shlibpath_var_CXX=no - ;; - ia64*) - hardcode_direct_CXX=no - hardcode_shlibpath_var_CXX=no - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - *) - hardcode_direct_CXX=yes - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aCC) - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' - ;; - *) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case "$host_cpu" in - ia64*|hppa*64*) - archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' - ;; - *) - archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - irix5* | irix6*) - case $cc_basename in - CC) - # SGI C++ - archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - else - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' - fi - fi - link_all_deplibs_CXX=yes - ;; - esac - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - ;; - linux*) - case $cc_basename in - KCC) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - - hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc) - # Intel C++ - with_gnu_ld=yes - archive_cmds_need_lc_CXX=no - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - cxx) - # Compaq C++ - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec_CXX='-rpath $libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - esac - ;; - lynxos*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - m88k*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - mvs*) - case $cc_basename in - cxx) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - netbsd* | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - hardcode_libdir_flag_spec_CXX='-R$libdir' - hardcode_direct_CXX=yes - hardcode_shlibpath_var_CXX=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - osf3*) - case $cc_basename in - KCC) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - hardcode_libdir_separator_CXX=: - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' - - ;; - RCC) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - cxx) - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - osf4* | osf5*) - case $cc_basename in - KCC) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - hardcode_libdir_separator_CXX=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' - ;; - RCC) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - cxx) - allow_undefined_flag_CXX=' -expect_unresolved \*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ - $rm $lib.exp' - - hardcode_libdir_flag_spec_CXX='-rpath $libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - psos*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - sco*) - archive_cmds_need_lc_CXX=no - case $cc_basename in - CC) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - lcc) - # Lucid - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - solaris*) - case $cc_basename in - CC) - # Sun C++ 4.2, 5.x and Centerline C++ - no_undefined_flag_CXX=' -zdefs' - archive_cmds_CXX='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - hardcode_libdir_flag_spec_CXX='-R$libdir' - hardcode_shlibpath_var_CXX=no - case $host_os in - solaris2.0-5 | solaris2.0-5.*) ;; - *) - # The C++ compiler is used as linker so we must use $wl - # flag to pass the commands to the underlying system - # linker. - # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - link_all_deplibs_CXX=yes - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[LR]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' - ;; - gcx) - # Green Hills C++ Compiler - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - no_undefined_flag_CXX=' ${wl}-z ${wl}defs' - if $CC --version | grep -v '^2\.7' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" - fi - - hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' - fi - ;; - esac - ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - archive_cmds_need_lc_CXX=no - ;; - tandem*) - case $cc_basename in - NCC) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - vxworks*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; -esac -echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 -echo "${ECHO_T}$ld_shlibs_CXX" >&6 -test "$ld_shlibs_CXX" = no && can_build_shared=no - -GCC_CXX="$GXX" -LD_CXX="$LD" - - -cat > conftest.$ac_ext <&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - # The `*' in the case matches for architectures that use `case' in - # $output_verbose_cmd can trigger glob expansion during the loop - # eval without this substitution. - output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`" - - for p in `eval $output_verbose_link_cmd`; do - case $p in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" \ - || test $p = "-R"; then - prev=$p - continue - else - prev= - fi - - if test "$pre_test_object_deps_done" = no; then - case $p in - -L* | -R*) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$compiler_lib_search_path_CXX"; then - compiler_lib_search_path_CXX="${prev}${p}" - else - compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$postdeps_CXX"; then - postdeps_CXX="${prev}${p}" - else - postdeps_CXX="${postdeps_CXX} ${prev}${p}" - fi - fi - ;; - - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$predep_objects_CXX"; then - predep_objects_CXX="$p" - else - predep_objects_CXX="$predep_objects_CXX $p" - fi - else - if test -z "$postdep_objects_CXX"; then - postdep_objects_CXX="$p" - else - postdep_objects_CXX="$postdep_objects_CXX $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling CXX test program" -fi - -$rm -f confest.$objext - -case " $postdeps_CXX " in -*" -lc "*) archive_cmds_need_lc_CXX=no ;; -esac - -lt_prog_compiler_wl_CXX= -lt_prog_compiler_pic_CXX= -lt_prog_compiler_static_CXX= - -echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 -echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 - - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_CXX='-Bstatic' - fi - ;; - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' - ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | os2* | pw32*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_CXX='-DDLL_EXPORT' - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic_CXX='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - lt_prog_compiler_pic_CXX= - ;; - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic_CXX=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case "$host_cpu" in - hppa*64*|ia64*) - ;; - *) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - esac - ;; - *) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - esac - else - case $host_os in - aix4* | aix5*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_CXX='-Bstatic' - else - lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68) - # Green Hills C++ Compiler - # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - dgux*) - case $cc_basename in - ec++) - lt_prog_compiler_pic_CXX='-KPIC' - ;; - ghcx) - # Green Hills C++ Compiler - lt_prog_compiler_pic_CXX='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | kfreebsd*-gnu) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - if test "$host_cpu" != ia64; then - lt_prog_compiler_pic_CXX='+Z' - fi - ;; - aCC) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - case "$host_cpu" in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_CXX='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux*) - case $cc_basename in - KCC) - # KAI C++ Compiler - lt_prog_compiler_wl_CXX='--backend -Wl,' - lt_prog_compiler_pic_CXX='-fPIC' - ;; - icpc) - # Intel C++ - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-static' - ;; - cxx) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - lt_prog_compiler_pic_CXX= - lt_prog_compiler_static_CXX='-non_shared' - ;; - *) - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx) - lt_prog_compiler_pic_CXX='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd* | knetbsd*-gnu) - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC) - lt_prog_compiler_wl_CXX='--backend -Wl,' - ;; - RCC) - # Rational C++ 2.4.1 - lt_prog_compiler_pic_CXX='-pic' - ;; - cxx) - # Digital/Compaq C++ - lt_prog_compiler_wl_CXX='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - lt_prog_compiler_pic_CXX= - lt_prog_compiler_static_CXX='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - sco*) - case $cc_basename in - CC) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - *) - ;; - esac - ;; - solaris*) - case $cc_basename in - CC) - # Sun C++ 4.2, 5.x and Centerline C++ - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-Bstatic' - lt_prog_compiler_wl_CXX='-Qoption ld ' - ;; - gcx) - # Green Hills C++ Compiler - lt_prog_compiler_pic_CXX='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC) - # Sun C++ 4.x - lt_prog_compiler_pic_CXX='-pic' - lt_prog_compiler_static_CXX='-Bstatic' - ;; - lcc) - # Lucid - lt_prog_compiler_pic_CXX='-pic' - ;; - *) - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC) - # NonStop-UX NCC 3.20 - lt_prog_compiler_pic_CXX='-KPIC' - ;; - *) - ;; - esac - ;; - unixware*) - ;; - vxworks*) - ;; - *) - lt_prog_compiler_can_build_shared_CXX=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6 - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic_CXX"; then - -echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 -echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6 -if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_pic_works_CXX=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10309: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:10313: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then - lt_prog_compiler_pic_works_CXX=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6 - -if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then - case $lt_prog_compiler_pic_CXX in - "" | " "*) ;; - *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; - esac -else - lt_prog_compiler_pic_CXX= - lt_prog_compiler_can_build_shared_CXX=no -fi - -fi -case "$host_os" in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic_CXX= - ;; - *) - lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" - ;; -esac - -echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 -echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_c_o_CXX=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10369: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:10373: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s out/conftest.err; then - lt_cv_prog_compiler_c_o_CXX=yes - fi - fi - chmod u+w . - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6 - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 -echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$as_me:$LINENO: result: $hard_links" >&5 -echo "${ECHO_T}$hard_links" >&6 - if test "$hard_links" = no; then - { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - -echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 - - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - case $host_os in - aix4* | aix5*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - export_symbols_cmds_CXX="$ltdll_cmds" - ;; - cygwin* | mingw*) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' - ;; - *) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac - -echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 -echo "${ECHO_T}$ld_shlibs_CXX" >&6 -test "$ld_shlibs_CXX" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc_CXX" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc_CXX=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds_CXX in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 -echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl_CXX - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag_CXX - allow_undefined_flag_CXX= - if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 - (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - then - archive_cmds_need_lc_CXX=no - else - archive_cmds_need_lc_CXX=yes - fi - allow_undefined_flag_CXX=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 -echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6 - ;; - esac - fi - ;; -esac - -echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 -echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi4*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext='$(test .$module = .yes && echo .so || echo .dylib)' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.01* | freebsdelf3.01*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case "$host_cpu" in - ia64*) - shrext='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf` - sys_lib_dlsearch_path_spec="/lib /usr/lib $ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - need_version=yes - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$as_me:$LINENO: result: $dynamic_linker" >&5 -echo "${ECHO_T}$dynamic_linker" >&6 -test "$dynamic_linker" = no && can_build_shared=no - -echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 -echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 -hardcode_action_CXX= -if test -n "$hardcode_libdir_flag_spec_CXX" || \ - test -n "$runpath_var CXX" || \ - test "X$hardcode_automatic_CXX"="Xyes" ; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct_CXX" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && - test "$hardcode_minus_L_CXX" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action_CXX=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action_CXX=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action_CXX=unsupported -fi -echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 -echo "${ECHO_T}$hardcode_action_CXX" >&6 - -if test "$hardcode_action_CXX" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - echo "$as_me:$LINENO: checking for shl_load" >&5 -echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 -if test "${ac_cv_func_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define shl_load to an innocuous variant, in case declares shl_load. - For example, HP-UX 11i declares gettimeofday. */ -#define shl_load innocuous_shl_load - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char shl_load (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef shl_load - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -char (*f) () = shl_load; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != shl_load; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 -echo "${ECHO_T}$ac_cv_func_shl_load" >&6 -if test $ac_cv_func_shl_load = yes; then - lt_cv_dlopen="shl_load" -else - echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -int -main () -{ -shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 -if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - echo "$as_me:$LINENO: checking for dlopen" >&5 -echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 -if test "${ac_cv_func_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define dlopen to an innocuous variant, in case declares dlopen. - For example, HP-UX 11i declares gettimeofday. */ -#define dlopen innocuous_dlopen - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char dlopen (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef dlopen - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -char (*f) () = dlopen; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != dlopen; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 -echo "${ECHO_T}$ac_cv_func_dlopen" >&6 -if test $ac_cv_func_dlopen = yes; then - lt_cv_dlopen="dlopen" -else - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 -echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 -if test "${ac_cv_lib_svld_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_svld_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_svld_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 -if test $ac_cv_lib_svld_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 -echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_dld_link+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dld_link (); -int -main () -{ -dld_link (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_dld_link=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_dld_link=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 -if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 -echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self" >&6 - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 -echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - -# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - compiler_CXX \ - CC_CXX \ - LD_CXX \ - lt_prog_compiler_wl_CXX \ - lt_prog_compiler_pic_CXX \ - lt_prog_compiler_static_CXX \ - lt_prog_compiler_no_builtin_flag_CXX \ - export_dynamic_flag_spec_CXX \ - thread_safe_flag_spec_CXX \ - whole_archive_flag_spec_CXX \ - enable_shared_with_static_runtimes_CXX \ - old_archive_cmds_CXX \ - old_archive_from_new_cmds_CXX \ - predep_objects_CXX \ - postdep_objects_CXX \ - predeps_CXX \ - postdeps_CXX \ - compiler_lib_search_path_CXX \ - archive_cmds_CXX \ - archive_expsym_cmds_CXX \ - postinstall_cmds_CXX \ - postuninstall_cmds_CXX \ - old_archive_from_expsyms_cmds_CXX \ - allow_undefined_flag_CXX \ - no_undefined_flag_CXX \ - export_symbols_cmds_CXX \ - hardcode_libdir_flag_spec_CXX \ - hardcode_libdir_flag_spec_ld_CXX \ - hardcode_libdir_separator_CXX \ - hardcode_automatic_CXX \ - module_cmds_CXX \ - module_expsym_cmds_CXX \ - lt_cv_prog_compiler_c_o_CXX \ - exclude_expsyms_CXX \ - include_expsyms_CXX; do - - case $var in - old_archive_cmds_CXX | \ - old_archive_from_new_cmds_CXX | \ - archive_cmds_CXX | \ - archive_expsym_cmds_CXX | \ - module_cmds_CXX | \ - module_expsym_cmds_CXX | \ - old_archive_from_expsyms_cmds_CXX | \ - export_symbols_cmds_CXX | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\$0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - -cfgfile="$ofile" - - cat <<__EOF__ >> "$cfgfile" -# ### BEGIN LIBTOOL TAG CONFIG: $tagname - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc_CXX - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_compiler_CXX - -# Is the compiler the GNU C compiler? -with_gcc=$GCC_CXX - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_LD_CXX - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_CXX - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext='$shrext' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic_CXX -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX - -# Must we lock files when doing compilation ? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static_CXX - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds_CXX -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds_CXX -archive_expsym_cmds=$lt_archive_expsym_cmds_CXX -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_module_cmds_CXX -module_expsym_cmds=$lt_module_expsym_cmds_CXX - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_predep_objects_CXX - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_postdep_objects_CXX - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_predeps_CXX - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_postdeps_CXX - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_CXX - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag_CXX - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag_CXX - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action_CXX - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct_CXX - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L_CXX - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$hardcode_automatic_CXX - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs_CXX - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_CXX" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols_CXX - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds_CXX - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms_CXX - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms_CXX - -# ### END LIBTOOL TAG CONFIG: $tagname - -__EOF__ - - -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC=$lt_save_CC -LDCXX=$LD -LD=$lt_save_LD -GCC=$lt_save_GCC -with_gnu_ldcxx=$with_gnu_ld -with_gnu_ld=$lt_save_with_gnu_ld -lt_cv_path_LDCXX=$lt_cv_path_LD -lt_cv_path_LD=$lt_save_path_LD -lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld -lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld - - else - tagname="" - fi - ;; - - F77) - if test -n "$F77" && test "X$F77" != "Xno"; then - -ac_ext=f -ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' -ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_f77_compiler_gnu - - -archive_cmds_need_lc_F77=no -allow_undefined_flag_F77= -always_export_symbols_F77=no -archive_expsym_cmds_F77= -export_dynamic_flag_spec_F77= -hardcode_direct_F77=no -hardcode_libdir_flag_spec_F77= -hardcode_libdir_flag_spec_ld_F77= -hardcode_libdir_separator_F77= -hardcode_minus_L_F77=no -hardcode_automatic_F77=no -module_cmds_F77= -module_expsym_cmds_F77= -link_all_deplibs_F77=unknown -old_archive_cmds_F77=$old_archive_cmds -no_undefined_flag_F77= -whole_archive_flag_spec_F77= -enable_shared_with_static_runtimes_F77=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -objext_F77=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code=" subroutine t\n return\n end\n" - -# Code to be used in simple link tests -lt_simple_link_test_code=" program t\n end\n" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -CC=${F77-"f77"} -compiler=$CC -compiler_F77=$CC -cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` - -echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 -echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $can_build_shared" >&5 -echo "${ECHO_T}$can_build_shared" >&6 - -echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 -echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case "$host_os" in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; -aix4*) - test "$enable_shared" = yes && enable_static=no - ;; -esac -echo "$as_me:$LINENO: result: $enable_shared" >&5 -echo "${ECHO_T}$enable_shared" >&6 - -echo "$as_me:$LINENO: checking whether to build static libraries" >&5 -echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes -echo "$as_me:$LINENO: result: $enable_static" >&5 -echo "${ECHO_T}$enable_static" >&6 - -test "$ld_shlibs_F77" = no && can_build_shared=no - -GCC_F77="$G77" -LD_F77="$LD" - -lt_prog_compiler_wl_F77= -lt_prog_compiler_pic_F77= -lt_prog_compiler_static_F77= - -echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 -echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 - - if test "$GCC" = yes; then - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_static_F77='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_F77='-Bstatic' - fi - ;; - - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' - ;; - - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_F77='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic_F77='-fno-common' - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared_F77=no - enable_shared=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic_F77=-Kconform_pic - fi - ;; - - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case "$host_cpu" in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_F77='-fPIC' - ;; - esac - ;; - - *) - lt_prog_compiler_pic_F77='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl_F77='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_F77='-Bstatic' - else - lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_F77='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl_F77='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case "$host_cpu" in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_F77='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static_F77='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl_F77='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static_F77='-non_shared' - ;; - - newsos6) - lt_prog_compiler_pic_F77='-KPIC' - lt_prog_compiler_static_F77='-Bstatic' - ;; - - linux*) - case $CC in - icc* | ecc*) - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_pic_F77='-KPIC' - lt_prog_compiler_static_F77='-static' - ;; - ccc*) - lt_prog_compiler_wl_F77='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static_F77='-non_shared' - ;; - esac - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl_F77='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static_F77='-non_shared' - ;; - - sco3.2v5*) - lt_prog_compiler_pic_F77='-Kpic' - lt_prog_compiler_static_F77='-dn' - ;; - - solaris*) - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_pic_F77='-KPIC' - lt_prog_compiler_static_F77='-Bstatic' - ;; - - sunos4*) - lt_prog_compiler_wl_F77='-Qoption ld ' - lt_prog_compiler_pic_F77='-PIC' - lt_prog_compiler_static_F77='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - lt_prog_compiler_wl_F77='-Wl,' - lt_prog_compiler_pic_F77='-KPIC' - lt_prog_compiler_static_F77='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic_F77='-Kconform_pic' - lt_prog_compiler_static_F77='-Bstatic' - fi - ;; - - uts4*) - lt_prog_compiler_pic_F77='-pic' - lt_prog_compiler_static_F77='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared_F77=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6 - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic_F77"; then - -echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 -echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6 -if test "${lt_prog_compiler_pic_works_F77+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_pic_works_F77=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic_F77" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12655: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:12659: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then - lt_prog_compiler_pic_works_F77=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6 - -if test x"$lt_prog_compiler_pic_works_F77" = xyes; then - case $lt_prog_compiler_pic_F77 in - "" | " "*) ;; - *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; - esac -else - lt_prog_compiler_pic_F77= - lt_prog_compiler_can_build_shared_F77=no -fi - -fi -case "$host_os" in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic_F77= - ;; - *) - lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" - ;; -esac - -echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 -echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_c_o_F77=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12715: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:12719: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s out/conftest.err; then - lt_cv_prog_compiler_c_o_F77=yes - fi - fi - chmod u+w . - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6 - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 -echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$as_me:$LINENO: result: $hard_links" >&5 -echo "${ECHO_T}$hard_links" >&6 - if test "$hard_links" = no; then - { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - -echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 - - runpath_var= - allow_undefined_flag_F77= - enable_shared_with_static_runtimes_F77=no - archive_cmds_F77= - archive_expsym_cmds_F77= - old_archive_From_new_cmds_F77= - old_archive_from_expsyms_cmds_F77= - export_dynamic_flag_spec_F77= - whole_archive_flag_spec_F77= - thread_safe_flag_spec_F77= - hardcode_libdir_flag_spec_F77= - hardcode_libdir_flag_spec_ld_F77= - hardcode_libdir_separator_F77= - hardcode_direct_F77=no - hardcode_minus_L_F77=no - hardcode_shlibpath_var_F77=unsupported - link_all_deplibs_F77=unknown - hardcode_automatic_F77=no - module_cmds_F77= - module_expsym_cmds_F77= - always_export_symbols_F77=no - export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms_F77= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - ld_shlibs_F77=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs_F77=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - fi - ;; - - amigaos*) - archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_minus_L_F77=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can't use - # them. - ld_shlibs_F77=no - ;; - - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag_F77=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs_F77=no - fi - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec_F77='-L$libdir' - allow_undefined_flag_F77=unsupported - always_export_symbols_F77=no - enable_shared_with_static_runtimes_F77=yes - export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - ld_shlibs=no - fi - ;; - - netbsd* | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - ld_shlibs_F77=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs_F77=no - fi - ;; - - sunos4*) - archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - linux*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_cmds_F77="$tmp_archive_cmds" - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - if test $supports_anon_versioning = yes; then - archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ -cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ -$echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - else - archive_expsym_cmds_F77="$tmp_archive_cmds" - fi - else - ld_shlibs_F77=no - fi - ;; - - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs_F77=no - fi - ;; - esac - - if test "$ld_shlibs_F77" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_F77='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec_F77= - fi - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag_F77=unsupported - always_export_symbols_F77=yes - archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L_F77=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct_F77=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds_F77='' - hardcode_direct_F77=yes - hardcode_libdir_separator_F77=':' - link_all_deplibs_F77=yes - - if test "$GCC" = yes; then - case $host_os in aix4.012|aix4.012.*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct_F77=yes - else - # We have old collect2 - hardcode_direct_F77=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L_F77=yes - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_libdir_separator_F77= - fi - esac - shared_flag='-shared' - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols_F77=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag_F77='-berok' - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF - program main - - end -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag_F77="-z nodefs" - archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF - program main - - end -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag_F77=' ${wl}-bernotok' - allow_undefined_flag_F77=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_F77=yes - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_F77=' ' - archive_cmds_need_lc_F77=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_minus_L_F77=yes - # see comment about different semantics on the GNU ld section - ld_shlibs_F77=no - ;; - - bsdi4*) - export_dynamic_flag_spec_F77=-rdynamic - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec_F77=' ' - allow_undefined_flag_F77=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_From_new_cmds_F77='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - enable_shared_with_static_runtimes_F77=yes - ;; - - darwin* | rhapsody*) - if test "$GXX" = yes ; then - archive_cmds_need_lc_F77=no - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag_F77='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag_F77='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag_F77='-flat_namespace -undefined suppress' - ;; - 10.*) - allow_undefined_flag_F77='-undefined dynamic_lookup' - ;; - esac - fi - ;; - esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_cmds_F77='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - archive_cmds_F77='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - module_cmds_F77='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - hardcode_direct_F77=no - hardcode_automatic_F77=yes - hardcode_shlibpath_var_F77=unsupported - whole_archive_flag_spec_F77='-all_load $convenience' - link_all_deplibs_F77=yes - else - ld_shlibs_F77=no - fi - ;; - - dgux*) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_shlibpath_var_F77=no - ;; - - freebsd1*) - ld_shlibs_F77=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec_F77='-R$libdir' - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=yes - hardcode_minus_L_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu) - archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_F77='-R$libdir' - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_F77=: - hardcode_direct_F77=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_F77=yes - export_dynamic_flag_spec_F77='${wl}-E' - ;; - - hpux10* | hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_F77='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' - ;; - *) - archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_F77='+b $libdir' - hardcode_libdir_separator_F77=: - hardcode_direct_F77=no - hardcode_shlibpath_var_F77=no - ;; - ia64*) - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_direct_F77=no - hardcode_shlibpath_var_F77=no - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_F77=yes - ;; - *) - hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_F77=: - hardcode_direct_F77=yes - export_dynamic_flag_spec_F77='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_F77=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' - fi - hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_F77=: - link_all_deplibs_F77=yes - ;; - - netbsd* | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec_F77='-R$libdir' - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - newsos6) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=yes - hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_F77=: - hardcode_shlibpath_var_F77=no - ;; - - openbsd*) - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' - export_dynamic_flag_spec_F77='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_F77='-R$libdir' - ;; - *) - archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_minus_L_F77=yes - allow_undefined_flag_F77=unsupported - archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag_F77=' -expect_unresolved \*' - archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_F77=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag_F77=' -expect_unresolved \*' - archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec_F77='-rpath $libdir' - fi - hardcode_libdir_separator_F77=: - ;; - - sco3.2v5*) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_F77=no - export_dynamic_flag_spec_F77='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - no_undefined_flag_F77=' -z text' - if test "$GCC" = yes; then - archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' - else - archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - fi - hardcode_libdir_flag_spec_F77='-R$libdir' - hardcode_shlibpath_var_F77=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; - esac - link_all_deplibs_F77=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_direct_F77=yes - hardcode_minus_L_F77=yes - hardcode_shlibpath_var_F77=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds_F77='$CC -r -o $output$reload_objs' - hardcode_direct_F77=no - ;; - motorola) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_F77=no - ;; - - sysv4.3*) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_F77=no - export_dynamic_flag_spec_F77='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_F77=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs_F77=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=yes - hardcode_minus_L_F77=no - hardcode_shlibpath_var_F77=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag_F77='${wl}-z ${wl}text' - if test "$GCC" = yes; then - archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds_F77='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_F77=no - ;; - - sysv5*) - no_undefined_flag_F77=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec_F77= - hardcode_shlibpath_var_F77=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_shlibpath_var_F77=no - ;; - - *) - ld_shlibs_F77=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 -echo "${ECHO_T}$ld_shlibs_F77" >&6 -test "$ld_shlibs_F77" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc_F77" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc_F77=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds_F77 in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 -echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl_F77 - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag_F77 - allow_undefined_flag_F77= - if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 - (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - then - archive_cmds_need_lc_F77=no - else - archive_cmds_need_lc_F77=yes - fi - allow_undefined_flag_F77=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 -echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6 - ;; - esac - fi - ;; -esac - -echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 -echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi4*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext='$(test .$module = .yes && echo .so || echo .dylib)' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.01* | freebsdelf3.01*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case "$host_cpu" in - ia64*) - shrext='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf` - sys_lib_dlsearch_path_spec="/lib /usr/lib $ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - need_version=yes - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$as_me:$LINENO: result: $dynamic_linker" >&5 -echo "${ECHO_T}$dynamic_linker" >&6 -test "$dynamic_linker" = no && can_build_shared=no - -echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 -echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 -hardcode_action_F77= -if test -n "$hardcode_libdir_flag_spec_F77" || \ - test -n "$runpath_var F77" || \ - test "X$hardcode_automatic_F77"="Xyes" ; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct_F77" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && - test "$hardcode_minus_L_F77" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action_F77=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action_F77=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action_F77=unsupported -fi -echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 -echo "${ECHO_T}$hardcode_action_F77" >&6 - -if test "$hardcode_action_F77" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - - - -# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - compiler_F77 \ - CC_F77 \ - LD_F77 \ - lt_prog_compiler_wl_F77 \ - lt_prog_compiler_pic_F77 \ - lt_prog_compiler_static_F77 \ - lt_prog_compiler_no_builtin_flag_F77 \ - export_dynamic_flag_spec_F77 \ - thread_safe_flag_spec_F77 \ - whole_archive_flag_spec_F77 \ - enable_shared_with_static_runtimes_F77 \ - old_archive_cmds_F77 \ - old_archive_from_new_cmds_F77 \ - predep_objects_F77 \ - postdep_objects_F77 \ - predeps_F77 \ - postdeps_F77 \ - compiler_lib_search_path_F77 \ - archive_cmds_F77 \ - archive_expsym_cmds_F77 \ - postinstall_cmds_F77 \ - postuninstall_cmds_F77 \ - old_archive_from_expsyms_cmds_F77 \ - allow_undefined_flag_F77 \ - no_undefined_flag_F77 \ - export_symbols_cmds_F77 \ - hardcode_libdir_flag_spec_F77 \ - hardcode_libdir_flag_spec_ld_F77 \ - hardcode_libdir_separator_F77 \ - hardcode_automatic_F77 \ - module_cmds_F77 \ - module_expsym_cmds_F77 \ - lt_cv_prog_compiler_c_o_F77 \ - exclude_expsyms_F77 \ - include_expsyms_F77; do - - case $var in - old_archive_cmds_F77 | \ - old_archive_from_new_cmds_F77 | \ - archive_cmds_F77 | \ - archive_expsym_cmds_F77 | \ - module_cmds_F77 | \ - module_expsym_cmds_F77 | \ - old_archive_from_expsyms_cmds_F77 | \ - export_symbols_cmds_F77 | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\$0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - -cfgfile="$ofile" - - cat <<__EOF__ >> "$cfgfile" -# ### BEGIN LIBTOOL TAG CONFIG: $tagname - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc_F77 - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_compiler_F77 - -# Is the compiler the GNU C compiler? -with_gcc=$GCC_F77 - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_LD_F77 - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_F77 - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext='$shrext' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic_F77 -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 - -# Must we lock files when doing compilation ? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static_F77 - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds_F77 -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds_F77 -archive_expsym_cmds=$lt_archive_expsym_cmds_F77 -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_module_cmds_F77 -module_expsym_cmds=$lt_module_expsym_cmds_F77 - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_predep_objects_F77 - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_postdep_objects_F77 - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_predeps_F77 - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_postdeps_F77 - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_F77 - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag_F77 - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag_F77 - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action_F77 - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct_F77 - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L_F77 - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$hardcode_automatic_F77 - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs_F77 - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_F77" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols_F77 - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds_F77 - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms_F77 - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms_F77 - -# ### END LIBTOOL TAG CONFIG: $tagname - -__EOF__ - - -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - else - tagname="" - fi - ;; - - GCJ) - if test -n "$GCJ" && test "X$GCJ" != "Xno"; then - - - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -objext_GCJ=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String argv) {}; }\n' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -CC=${GCJ-"gcj"} -compiler=$CC -compiler_GCJ=$CC - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -archive_cmds_need_lc_GCJ=no - - -lt_prog_compiler_no_builtin_flag_GCJ= - -if test "$GCC" = yes; then - lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' - - -echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14749: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:14753: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 - -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then - lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" -else - : -fi - -fi - -lt_prog_compiler_wl_GCJ= -lt_prog_compiler_pic_GCJ= -lt_prog_compiler_static_GCJ= - -echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 -echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 - - if test "$GCC" = yes; then - lt_prog_compiler_wl_GCJ='-Wl,' - lt_prog_compiler_static_GCJ='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_GCJ='-Bstatic' - fi - ;; - - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' - ;; - - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic_GCJ='-fno-common' - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared_GCJ=no - enable_shared=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic_GCJ=-Kconform_pic - fi - ;; - - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case "$host_cpu" in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_GCJ='-fPIC' - ;; - esac - ;; - - *) - lt_prog_compiler_pic_GCJ='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl_GCJ='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_GCJ='-Bstatic' - else - lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl_GCJ='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case "$host_cpu" in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_GCJ='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl_GCJ='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static_GCJ='-non_shared' - ;; - - newsos6) - lt_prog_compiler_pic_GCJ='-KPIC' - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - - linux*) - case $CC in - icc* | ecc*) - lt_prog_compiler_wl_GCJ='-Wl,' - lt_prog_compiler_pic_GCJ='-KPIC' - lt_prog_compiler_static_GCJ='-static' - ;; - ccc*) - lt_prog_compiler_wl_GCJ='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static_GCJ='-non_shared' - ;; - esac - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl_GCJ='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static_GCJ='-non_shared' - ;; - - sco3.2v5*) - lt_prog_compiler_pic_GCJ='-Kpic' - lt_prog_compiler_static_GCJ='-dn' - ;; - - solaris*) - lt_prog_compiler_wl_GCJ='-Wl,' - lt_prog_compiler_pic_GCJ='-KPIC' - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - - sunos4*) - lt_prog_compiler_wl_GCJ='-Qoption ld ' - lt_prog_compiler_pic_GCJ='-PIC' - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - lt_prog_compiler_wl_GCJ='-Wl,' - lt_prog_compiler_pic_GCJ='-KPIC' - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic_GCJ='-Kconform_pic' - lt_prog_compiler_static_GCJ='-Bstatic' - fi - ;; - - uts4*) - lt_prog_compiler_pic_GCJ='-pic' - lt_prog_compiler_static_GCJ='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared_GCJ=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6 - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic_GCJ"; then - -echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 -echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6 -if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_pic_works_GCJ=no - ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic_GCJ" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14982: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:14986: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then - lt_prog_compiler_pic_works_GCJ=yes - fi - fi - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6 - -if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then - case $lt_prog_compiler_pic_GCJ in - "" | " "*) ;; - *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; - esac -else - lt_prog_compiler_pic_GCJ= - lt_prog_compiler_can_build_shared_GCJ=no -fi - -fi -case "$host_os" in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic_GCJ= - ;; - *) - lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" - ;; -esac - -echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 -echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 -if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_cv_prog_compiler_c_o_GCJ=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15042: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:15046: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s out/conftest.err; then - lt_cv_prog_compiler_c_o_GCJ=yes - fi - fi - chmod u+w . - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* - -fi -echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 -echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6 - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 -echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$as_me:$LINENO: result: $hard_links" >&5 -echo "${ECHO_T}$hard_links" >&6 - if test "$hard_links" = no; then - { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - -echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 - - runpath_var= - allow_undefined_flag_GCJ= - enable_shared_with_static_runtimes_GCJ=no - archive_cmds_GCJ= - archive_expsym_cmds_GCJ= - old_archive_From_new_cmds_GCJ= - old_archive_from_expsyms_cmds_GCJ= - export_dynamic_flag_spec_GCJ= - whole_archive_flag_spec_GCJ= - thread_safe_flag_spec_GCJ= - hardcode_libdir_flag_spec_GCJ= - hardcode_libdir_flag_spec_ld_GCJ= - hardcode_libdir_separator_GCJ= - hardcode_direct_GCJ=no - hardcode_minus_L_GCJ=no - hardcode_shlibpath_var_GCJ=unsupported - link_all_deplibs_GCJ=unknown - hardcode_automatic_GCJ=no - module_cmds_GCJ= - module_expsym_cmds_GCJ= - always_export_symbols_GCJ=no - export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms_GCJ= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - ld_shlibs_GCJ=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs_GCJ=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - fi - ;; - - amigaos*) - archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_minus_L_GCJ=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can't use - # them. - ld_shlibs_GCJ=no - ;; - - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag_GCJ=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs_GCJ=no - fi - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec_GCJ='-L$libdir' - allow_undefined_flag_GCJ=unsupported - always_export_symbols_GCJ=no - enable_shared_with_static_runtimes_GCJ=yes - export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - ld_shlibs=no - fi - ;; - - netbsd* | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - ld_shlibs_GCJ=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs_GCJ=no - fi - ;; - - sunos4*) - archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - linux*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_cmds_GCJ="$tmp_archive_cmds" - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - if test $supports_anon_versioning = yes; then - archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ -cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ -$echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - else - archive_expsym_cmds_GCJ="$tmp_archive_cmds" - fi - else - ld_shlibs_GCJ=no - fi - ;; - - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs_GCJ=no - fi - ;; - esac - - if test "$ld_shlibs_GCJ" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec_GCJ= - fi - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag_GCJ=unsupported - always_export_symbols_GCJ=yes - archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L_GCJ=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct_GCJ=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds_GCJ='' - hardcode_direct_GCJ=yes - hardcode_libdir_separator_GCJ=':' - link_all_deplibs_GCJ=yes - - if test "$GCC" = yes; then - case $host_os in aix4.012|aix4.012.*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct_GCJ=yes - else - # We have old collect2 - hardcode_direct_GCJ=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L_GCJ=yes - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_libdir_separator_GCJ= - fi - esac - shared_flag='-shared' - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols_GCJ=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag_GCJ='-berok' - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag_GCJ="-z nodefs" - archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag_GCJ=' ${wl}-bernotok' - allow_undefined_flag_GCJ=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_GCJ=yes - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_GCJ=' ' - archive_cmds_need_lc_GCJ=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_minus_L_GCJ=yes - # see comment about different semantics on the GNU ld section - ld_shlibs_GCJ=no - ;; - - bsdi4*) - export_dynamic_flag_spec_GCJ=-rdynamic - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec_GCJ=' ' - allow_undefined_flag_GCJ=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_From_new_cmds_GCJ='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - enable_shared_with_static_runtimes_GCJ=yes - ;; - - darwin* | rhapsody*) - if test "$GXX" = yes ; then - archive_cmds_need_lc_GCJ=no - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag_GCJ='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag_GCJ='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag_GCJ='-flat_namespace -undefined suppress' - ;; - 10.*) - allow_undefined_flag_GCJ='-undefined dynamic_lookup' - ;; - esac - fi - ;; - esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_cmds_GCJ='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - archive_cmds_GCJ='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - module_cmds_GCJ='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - hardcode_direct_GCJ=no - hardcode_automatic_GCJ=yes - hardcode_shlibpath_var_GCJ=unsupported - whole_archive_flag_spec_GCJ='-all_load $convenience' - link_all_deplibs_GCJ=yes - else - ld_shlibs_GCJ=no - fi - ;; - - dgux*) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_shlibpath_var_GCJ=no - ;; - - freebsd1*) - ld_shlibs_GCJ=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec_GCJ='-R$libdir' - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=yes - hardcode_minus_L_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu) - archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_GCJ='-R$libdir' - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_GCJ=: - hardcode_direct_GCJ=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_GCJ=yes - export_dynamic_flag_spec_GCJ='${wl}-E' - ;; - - hpux10* | hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_GCJ='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' - ;; - *) - archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' - hardcode_libdir_separator_GCJ=: - hardcode_direct_GCJ=no - hardcode_shlibpath_var_GCJ=no - ;; - ia64*) - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_direct_GCJ=no - hardcode_shlibpath_var_GCJ=no - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_GCJ=yes - ;; - *) - hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_GCJ=: - hardcode_direct_GCJ=yes - export_dynamic_flag_spec_GCJ='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_GCJ=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' - fi - hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_GCJ=: - link_all_deplibs_GCJ=yes - ;; - - netbsd* | knetbsd*-gnu) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec_GCJ='-R$libdir' - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - newsos6) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=yes - hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_GCJ=: - hardcode_shlibpath_var_GCJ=no - ;; - - openbsd*) - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' - export_dynamic_flag_spec_GCJ='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_GCJ='-R$libdir' - ;; - *) - archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_minus_L_GCJ=yes - allow_undefined_flag_GCJ=unsupported - archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag_GCJ=' -expect_unresolved \*' - archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_GCJ=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag_GCJ=' -expect_unresolved \*' - archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec_GCJ='-rpath $libdir' - fi - hardcode_libdir_separator_GCJ=: - ;; - - sco3.2v5*) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_GCJ=no - export_dynamic_flag_spec_GCJ='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - no_undefined_flag_GCJ=' -z text' - if test "$GCC" = yes; then - archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' - else - archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - fi - hardcode_libdir_flag_spec_GCJ='-R$libdir' - hardcode_shlibpath_var_GCJ=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; - esac - link_all_deplibs_GCJ=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_direct_GCJ=yes - hardcode_minus_L_GCJ=yes - hardcode_shlibpath_var_GCJ=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds_GCJ='$CC -r -o $output$reload_objs' - hardcode_direct_GCJ=no - ;; - motorola) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_GCJ=no - ;; - - sysv4.3*) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_GCJ=no - export_dynamic_flag_spec_GCJ='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_GCJ=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs_GCJ=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=yes - hardcode_minus_L_GCJ=no - hardcode_shlibpath_var_GCJ=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag_GCJ='${wl}-z ${wl}text' - if test "$GCC" = yes; then - archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds_GCJ='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_GCJ=no - ;; - - sysv5*) - no_undefined_flag_GCJ=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec_GCJ= - hardcode_shlibpath_var_GCJ=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_shlibpath_var_GCJ=no - ;; - - *) - ld_shlibs_GCJ=no - ;; - esac - fi - -echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 -echo "${ECHO_T}$ld_shlibs_GCJ" >&6 -test "$ld_shlibs_GCJ" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc_GCJ" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc_GCJ=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds_GCJ in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 -echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl_GCJ - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ - allow_undefined_flag_GCJ= - if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 - (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - then - archive_cmds_need_lc_GCJ=no - else - archive_cmds_need_lc_GCJ=yes - fi - allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 -echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6 - ;; - esac - fi - ;; -esac - -echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 -echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi4*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext='$(test .$module = .yes && echo .so || echo .dylib)' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.01* | freebsdelf3.01*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case "$host_cpu" in - ia64*) - shrext='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf` - sys_lib_dlsearch_path_spec="/lib /usr/lib $ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - need_version=yes - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$as_me:$LINENO: result: $dynamic_linker" >&5 -echo "${ECHO_T}$dynamic_linker" >&6 -test "$dynamic_linker" = no && can_build_shared=no - -echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 -echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 -hardcode_action_GCJ= -if test -n "$hardcode_libdir_flag_spec_GCJ" || \ - test -n "$runpath_var GCJ" || \ - test "X$hardcode_automatic_GCJ"="Xyes" ; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct_GCJ" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && - test "$hardcode_minus_L_GCJ" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action_GCJ=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action_GCJ=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action_GCJ=unsupported -fi -echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 -echo "${ECHO_T}$hardcode_action_GCJ" >&6 - -if test "$hardcode_action_GCJ" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - echo "$as_me:$LINENO: checking for shl_load" >&5 -echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 -if test "${ac_cv_func_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define shl_load to an innocuous variant, in case declares shl_load. - For example, HP-UX 11i declares gettimeofday. */ -#define shl_load innocuous_shl_load - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char shl_load (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef shl_load - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -char (*f) () = shl_load; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != shl_load; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 -echo "${ECHO_T}$ac_cv_func_shl_load" >&6 -if test $ac_cv_func_shl_load = yes; then - lt_cv_dlopen="shl_load" -else - echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -int -main () -{ -shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 -if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - echo "$as_me:$LINENO: checking for dlopen" >&5 -echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 -if test "${ac_cv_func_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define dlopen to an innocuous variant, in case declares dlopen. - For example, HP-UX 11i declares gettimeofday. */ -#define dlopen innocuous_dlopen - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char dlopen (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef dlopen - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -char (*f) () = dlopen; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != dlopen; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 -echo "${ECHO_T}$ac_cv_func_dlopen" >&6 -if test $ac_cv_func_dlopen = yes; then - lt_cv_dlopen="dlopen" -else - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 -echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 -if test "${ac_cv_lib_svld_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_svld_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_svld_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 -if test $ac_cv_lib_svld_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 -echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_dld_link+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dld_link (); -int -main () -{ -dld_link (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_dld_link=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_dld_link=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 -if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 -echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self" >&6 - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 -echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - -# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - compiler_GCJ \ - CC_GCJ \ - LD_GCJ \ - lt_prog_compiler_wl_GCJ \ - lt_prog_compiler_pic_GCJ \ - lt_prog_compiler_static_GCJ \ - lt_prog_compiler_no_builtin_flag_GCJ \ - export_dynamic_flag_spec_GCJ \ - thread_safe_flag_spec_GCJ \ - whole_archive_flag_spec_GCJ \ - enable_shared_with_static_runtimes_GCJ \ - old_archive_cmds_GCJ \ - old_archive_from_new_cmds_GCJ \ - predep_objects_GCJ \ - postdep_objects_GCJ \ - predeps_GCJ \ - postdeps_GCJ \ - compiler_lib_search_path_GCJ \ - archive_cmds_GCJ \ - archive_expsym_cmds_GCJ \ - postinstall_cmds_GCJ \ - postuninstall_cmds_GCJ \ - old_archive_from_expsyms_cmds_GCJ \ - allow_undefined_flag_GCJ \ - no_undefined_flag_GCJ \ - export_symbols_cmds_GCJ \ - hardcode_libdir_flag_spec_GCJ \ - hardcode_libdir_flag_spec_ld_GCJ \ - hardcode_libdir_separator_GCJ \ - hardcode_automatic_GCJ \ - module_cmds_GCJ \ - module_expsym_cmds_GCJ \ - lt_cv_prog_compiler_c_o_GCJ \ - exclude_expsyms_GCJ \ - include_expsyms_GCJ; do - - case $var in - old_archive_cmds_GCJ | \ - old_archive_from_new_cmds_GCJ | \ - archive_cmds_GCJ | \ - archive_expsym_cmds_GCJ | \ - module_cmds_GCJ | \ - module_expsym_cmds_GCJ | \ - old_archive_from_expsyms_cmds_GCJ | \ - export_symbols_cmds_GCJ | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\$0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - -cfgfile="$ofile" - - cat <<__EOF__ >> "$cfgfile" -# ### BEGIN LIBTOOL TAG CONFIG: $tagname - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc_GCJ - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_compiler_GCJ - -# Is the compiler the GNU C compiler? -with_gcc=$GCC_GCJ - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_LD_GCJ - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_GCJ - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext='$shrext' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic_GCJ -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ - -# Must we lock files when doing compilation ? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static_GCJ - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds_GCJ -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds_GCJ -archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_module_cmds_GCJ -module_expsym_cmds=$lt_module_expsym_cmds_GCJ - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_predep_objects_GCJ - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_postdep_objects_GCJ - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_predeps_GCJ - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_postdeps_GCJ - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag_GCJ - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag_GCJ - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action_GCJ - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct_GCJ - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L_GCJ - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$hardcode_automatic_GCJ - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs_GCJ - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_GCJ" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols_GCJ - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds_GCJ - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms_GCJ - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms_GCJ - -# ### END LIBTOOL TAG CONFIG: $tagname - -__EOF__ - - -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - else - tagname="" - fi - ;; - - RC) - - - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -objext_RC=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -CC=${RC-"windres"} -compiler=$CC -compiler_RC=$CC -lt_cv_prog_compiler_c_o_RC=yes - -# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - compiler_RC \ - CC_RC \ - LD_RC \ - lt_prog_compiler_wl_RC \ - lt_prog_compiler_pic_RC \ - lt_prog_compiler_static_RC \ - lt_prog_compiler_no_builtin_flag_RC \ - export_dynamic_flag_spec_RC \ - thread_safe_flag_spec_RC \ - whole_archive_flag_spec_RC \ - enable_shared_with_static_runtimes_RC \ - old_archive_cmds_RC \ - old_archive_from_new_cmds_RC \ - predep_objects_RC \ - postdep_objects_RC \ - predeps_RC \ - postdeps_RC \ - compiler_lib_search_path_RC \ - archive_cmds_RC \ - archive_expsym_cmds_RC \ - postinstall_cmds_RC \ - postuninstall_cmds_RC \ - old_archive_from_expsyms_cmds_RC \ - allow_undefined_flag_RC \ - no_undefined_flag_RC \ - export_symbols_cmds_RC \ - hardcode_libdir_flag_spec_RC \ - hardcode_libdir_flag_spec_ld_RC \ - hardcode_libdir_separator_RC \ - hardcode_automatic_RC \ - module_cmds_RC \ - module_expsym_cmds_RC \ - lt_cv_prog_compiler_c_o_RC \ - exclude_expsyms_RC \ - include_expsyms_RC; do - - case $var in - old_archive_cmds_RC | \ - old_archive_from_new_cmds_RC | \ - archive_cmds_RC | \ - archive_expsym_cmds_RC | \ - module_cmds_RC | \ - module_expsym_cmds_RC | \ - old_archive_from_expsyms_cmds_RC | \ - export_symbols_cmds_RC | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\$0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - -cfgfile="$ofile" - - cat <<__EOF__ >> "$cfgfile" -# ### BEGIN LIBTOOL TAG CONFIG: $tagname - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc_RC - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_compiler_RC - -# Is the compiler the GNU C compiler? -with_gcc=$GCC_RC - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_LD_RC - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_RC - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext='$shrext' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic_RC -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC - -# Must we lock files when doing compilation ? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static_RC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds_RC -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds_RC -archive_expsym_cmds=$lt_archive_expsym_cmds_RC -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_module_cmds_RC -module_expsym_cmds=$lt_module_expsym_cmds_RC - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_predep_objects_RC - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_postdep_objects_RC - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_predeps_RC - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_postdeps_RC - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_RC - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag_RC - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag_RC - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action_RC - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct_RC - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L_RC - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var_RC - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$hardcode_automatic_RC - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs_RC - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_RC" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols_RC - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds_RC - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms_RC - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms_RC - -# ### END LIBTOOL TAG CONFIG: $tagname - -__EOF__ - - -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - ;; - - *) - { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 -echo "$as_me: error: Unsupported tag name: $tagname" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - - # Append the new tag name to the list of available tags. - if test -n "$tagname" ; then - available_tags="$available_tags $tagname" - fi - fi - done - IFS="$lt_save_ifs" - - # Now substitute the updated list of available tags. - if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then - mv "${ofile}T" "$ofile" - chmod +x "$ofile" - else - rm -f "${ofile}T" - { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 -echo "$as_me: error: unable to update list of available tagged configurations." >&2;} - { (exit 1); exit 1; }; } - fi -fi - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - -# Prevent multiple expansion - - - - - - - - - - - - - - - - - - - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in - ./ | .// | /cC/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - done - done - ;; -esac -done - - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL=$ac_install_sh - fi -fi -echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$INSTALL" >&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - - -######### -# Set up an appropriate program prefix -# -if test "$program_prefix" = "NONE"; then - program_prefix="" -fi - - -VERSION=`cat $srcdir/VERSION | sed 's/^\([0-9]*\.*[0-9]*\).*/\1/'` -echo "Version set to $VERSION" - -RELEASE=`cat $srcdir/VERSION` -echo "Release set to $RELEASE" - -VERSION_NUMBER=`cat $srcdir/VERSION \ - | sed 's/[^0-9]/ /g' \ - | awk '{printf "%d%03d%03d",$1,$2,$3}'` - -echo "Version number set to $VERSION_NUMBER" - -######### -# Check to see if the --with-hints=FILE option is used. If there is none, -# then check for a files named "$host.hints" and ../$hosts.hints where -# $host is the hostname of the build system. If still no hints are -# found, try looking in $system.hints and ../$system.hints where -# $system is the result of uname -s. -# - -# Check whether --with-hints or --without-hints was given. -if test "${with_hints+set}" = set; then - withval="$with_hints" - hints=$withval -fi; -if test "$hints" = ""; then - host=`hostname | sed 's/\..*//'` - if test -r $host.hints; then - hints=$host.hints - else - if test -r ../$host.hints; then - hints=../$host.hints - fi - fi -fi -if test "$hints" = ""; then - sys=`uname -s` - if test -r $sys.hints; then - hints=$sys.hints - else - if test -r ../$sys.hints; then - hints=../$sys.hints - fi - fi -fi -if test "$hints" != ""; then - echo "$as_me:$LINENO: result: reading hints from $hints" >&5 -echo "${ECHO_T}reading hints from $hints" >&6 - . $hints -fi - -######### -# Locate a compiler for the build machine. This compiler should -# generate command-line programs that run on the build machine. -# -default_build_cflags="-g" -if test "$config_BUILD_CC" = ""; then - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CC" && break -done - - CC=$ac_ct_CC -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_cc_g=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 -echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_stdc=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std1 is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std1. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX 10.20 and later -Ae -# HP-UX older versions -Aa -D_HPUX_SOURCE -# SVR4 -Xc -D__EXTENSIONS__ -for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_stdc=$ac_arg -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext -done -rm -f conftest.$ac_ext conftest.$ac_objext -CC=$ac_save_CC - -fi - -case "x$ac_cv_prog_cc_stdc" in - x|xno) - echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6 ;; - *) - echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 - CC="$CC $ac_cv_prog_cc_stdc" ;; -esac - -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - if test "$cross_compiling" = "yes"; then - { { echo "$as_me:$LINENO: error: unable to find a compiler for building build tools" >&5 -echo "$as_me: error: unable to find a compiler for building build tools" >&2;} - { (exit 1); exit 1; }; } - fi - BUILD_CC=$CC - default_build_cflags=$CFLAGS -else - BUILD_CC=$config_BUILD_CC - echo "$as_me:$LINENO: checking host compiler" >&5 -echo $ECHO_N "checking host compiler... $ECHO_C" >&6 - CC=$BUILD_CC - echo "$as_me:$LINENO: result: $BUILD_CC" >&5 -echo "${ECHO_T}$BUILD_CC" >&6 -fi -echo "$as_me:$LINENO: checking switches for the host compiler" >&5 -echo $ECHO_N "checking switches for the host compiler... $ECHO_C" >&6 -if test "$config_BUILD_CFLAGS" != ""; then - CFLAGS=$config_BUILD_CFLAGS - BUILD_CFLAGS=$config_BUILD_CFLAGS -else - BUILD_CFLAGS=$default_build_cflags -fi -echo "$as_me:$LINENO: result: $BUILD_CFLAGS" >&5 -echo "${ECHO_T}$BUILD_CFLAGS" >&6 -if test "$config_BUILD_LIBS" != ""; then - BUILD_LIBS=$config_BUILD_LIBS -fi - - - - -########## -# Locate a compiler that converts C code into *.o files that run on -# the target machine. -# -echo "$as_me:$LINENO: checking target compiler" >&5 -echo $ECHO_N "checking target compiler... $ECHO_C" >&6 -if test "$config_TARGET_CC" != ""; then - TARGET_CC=$config_TARGET_CC -else - TARGET_CC=$BUILD_CC -fi -echo "$as_me:$LINENO: result: $TARGET_CC" >&5 -echo "${ECHO_T}$TARGET_CC" >&6 -echo "$as_me:$LINENO: checking switches on the target compiler" >&5 -echo $ECHO_N "checking switches on the target compiler... $ECHO_C" >&6 -if test "$config_TARGET_CFLAGS" != ""; then - TARGET_CFLAGS=$config_TARGET_CFLAGS -else - TARGET_CFLAGS=$BUILD_CFLAGS -fi -echo "$as_me:$LINENO: result: $TARGET_CFLAGS" >&5 -echo "${ECHO_T}$TARGET_CFLAGS" >&6 -echo "$as_me:$LINENO: checking target linker" >&5 -echo $ECHO_N "checking target linker... $ECHO_C" >&6 -if test "$config_TARGET_LINK" = ""; then - TARGET_LINK=$TARGET_CC -else - TARGET_LINK=$config_TARGET_LINK -fi -echo "$as_me:$LINENO: result: $TARGET_LINK" >&5 -echo "${ECHO_T}$TARGET_LINK" >&6 -echo "$as_me:$LINENO: checking switches on the target compiler" >&5 -echo $ECHO_N "checking switches on the target compiler... $ECHO_C" >&6 -if test "$config_TARGET_TFLAGS" != ""; then - TARGET_TFLAGS=$config_TARGET_TFLAGS -else - TARGET_TFLAGS=$BUILD_CFLAGS -fi -if test "$config_TARGET_RANLIB" != ""; then - TARGET_RANLIB=$config_TARGET_RANLIB -else - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - RANLIB=$ac_ct_RANLIB -else - RANLIB="$ac_cv_prog_RANLIB" -fi - - TARGET_RANLIB=$RANLIB -fi -if test "$config_TARGET_AR" != ""; then - TARGET_AR=$config_TARGET_AR -else - TARGET_AR='ar cr' -fi -echo "$as_me:$LINENO: result: $TARGET_TFLAGS" >&5 -echo "${ECHO_T}$TARGET_TFLAGS" >&6 - - - - - - - -# Set the $cross variable if we are cross-compiling. Make -# it 0 if we are not. -# -echo "$as_me:$LINENO: checking if host and target compilers are the same" >&5 -echo $ECHO_N "checking if host and target compilers are the same... $ECHO_C" >&6 -if test "$BUILD_CC" = "$TARGET_CC"; then - cross=0 - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else - cross=1 - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -########## -# Do we want to support multithreaded use of sqlite -# -# Check whether --enable-threadsafe or --disable-threadsafe was given. -if test "${enable_threadsafe+set}" = set; then - enableval="$enable_threadsafe" - -else - enable_threadsafe=no -fi; -echo "$as_me:$LINENO: checking whether to support threadsafe operation" >&5 -echo $ECHO_N "checking whether to support threadsafe operation... $ECHO_C" >&6 -if test "$enable_threadsafe" = "no"; then - THREADSAFE=0 - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -else - THREADSAFE=1 - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -fi - - -if test "$THREADSAFE" = "1"; then - LIBS="" - -echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 -echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6 -if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char pthread_create (); -int -main () -{ -pthread_create (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_pthread_pthread_create=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_pthread_pthread_create=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5 -echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6 -if test $ac_cv_lib_pthread_pthread_create = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBPTHREAD 1 -_ACEOF - - LIBS="-lpthread $LIBS" - -fi - - TARGET_THREAD_LIB="$LIBS" - LIBS="" -else - TARGET_THREAD_LIB="" -fi - - -########## -# Do we want to support release -# -# Check whether --enable-releasemode or --disable-releasemode was given. -if test "${enable_releasemode+set}" = set; then - enableval="$enable_releasemode" - -else - enable_releasemode=no -fi; -echo "$as_me:$LINENO: checking whether to support shared library linked as release mode or not" >&5 -echo $ECHO_N "checking whether to support shared library linked as release mode or not... $ECHO_C" >&6 -if test "$enable_releasemode" = "no"; then - ALLOWRELEASE="" - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -else - ALLOWRELEASE="-release `cat VERSION`" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -fi - - -########## -# Do we want temporary databases in memory -# -# Check whether --enable-tempstore or --disable-tempstore was given. -if test "${enable_tempstore+set}" = set; then - enableval="$enable_tempstore" - -else - enable_tempstore=yes -fi; -echo "$as_me:$LINENO: checking whether to use an in-ram database for temporary tables" >&5 -echo $ECHO_N "checking whether to use an in-ram database for temporary tables... $ECHO_C" >&6 -case "$enable_tempstore" in - never ) - TEMP_STORE=0 - echo "$as_me:$LINENO: result: never" >&5 -echo "${ECHO_T}never" >&6 - ;; - no ) - TEMP_STORE=1 - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - always ) - TEMP_STORE=3 - echo "$as_me:$LINENO: result: always" >&5 -echo "${ECHO_T}always" >&6 - ;; - * ) - TEMP_STORE=2 - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - ;; -esac - - - -########### -# Lots of things are different if we are compiling for Windows using -# the CYGWIN environment. So check for that special case and handle -# things accordingly. -# -echo "$as_me:$LINENO: checking if executables have the .exe suffix" >&5 -echo $ECHO_N "checking if executables have the .exe suffix... $ECHO_C" >&6 -if test "$config_BUILD_EXEEXT" = ".exe"; then - CYGWIN=yes - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else - echo "$as_me:$LINENO: result: unknown" >&5 -echo "${ECHO_T}unknown" >&6 -fi -if test "$CYGWIN" != "yes"; then - -case $host_os in - *cygwin* ) CYGWIN=yes;; - * ) CYGWIN=no;; -esac - -fi -if test "$CYGWIN" = "yes"; then - BUILD_EXEEXT=.exe -else - BUILD_EXEEXT=$EXEEXT -fi -if test "$cross" = "0"; then - TARGET_EXEEXT=$BUILD_EXEEXT -else - TARGET_EXEEXT=$config_TARGET_EXEEXT -fi -if test "$TARGET_EXEEXT" = ".exe"; then - OS_UNIX=0 - OS_WIN=1 - tclsubdir=win - TARGET_CFLAGS="$TARGET_CFLAGS -DOS_WIN=1" -else - OS_UNIX=1 - OS_WIN=0 - tclsubdir=unix - TARGET_CFLAGS="$TARGET_CFLAGS -DOS_UNIX=1" -fi - - - - - - -########## -# Extract generic linker options from the environment. -# -if test "$config_TARGET_LIBS" != ""; then - TARGET_LIBS=$config_TARGET_LIBS -else - TARGET_LIBS="" -fi - - -########## -# Figure out all the parameters needed to compile against Tcl. -# -# This code is derived from the SC_PATH_TCLCONFIG and SC_LOAD_TCLCONFIG -# macros in the in the tcl.m4 file of the standard TCL distribution. -# Those macros could not be used directly since we have to make some -# minor changes to accomodate systems that do not have TCL installed. -# -# Check whether --enable-tcl or --disable-tcl was given. -if test "${enable_tcl+set}" = set; then - enableval="$enable_tcl" - use_tcl=$enableval -else - use_tcl=yes -fi; -if test "${use_tcl}" = "yes" ; then - -# Check whether --with-tcl or --without-tcl was given. -if test "${with_tcl+set}" = set; then - withval="$with_tcl" - with_tclconfig=${withval} -fi; - echo "$as_me:$LINENO: checking for Tcl configuration" >&5 -echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6 - if test "${ac_cv_c_tclconfig+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - # First check to see if --with-tcl was specified. - if test x"${with_tclconfig}" != x ; then - if test -f "${with_tclconfig}/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` - else - { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 -echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;} - { (exit 1); exit 1; }; } - fi - fi - # then check for a private Tcl installation - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ../tcl \ - `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ - ../../tcl \ - `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ - ../../../tcl \ - `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` - do - if test -f "$i/unix/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i/unix; pwd)` - break - fi - done - fi - - # check in a few common install locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - `ls -d ${libdir} 2>/dev/null` \ - `ls -d /usr/local/lib 2>/dev/null` \ - `ls -d /usr/contrib/lib 2>/dev/null` \ - `ls -d /usr/lib 2>/dev/null` - do - if test -f "$i/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i; pwd)` - break - fi - done - fi - - # check in a few other private locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ${srcdir}/../tcl \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` - do - if test -f "$i/unix/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i/unix; pwd)` - break - fi - done - fi - -fi - - - if test x"${ac_cv_c_tclconfig}" = x ; then - use_tcl=no - { echo "$as_me:$LINENO: WARNING: Can't find Tcl configuration definitions" >&5 -echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;} - { echo "$as_me:$LINENO: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&5 -echo "$as_me: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&2;} - { echo "$as_me:$LINENO: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&5 -echo "$as_me: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&2;} - else - TCL_BIN_DIR=${ac_cv_c_tclconfig} - echo "$as_me:$LINENO: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 -echo "${ECHO_T}found $TCL_BIN_DIR/tclConfig.sh" >&6 - - echo "$as_me:$LINENO: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 -echo $ECHO_N "checking for existence of $TCL_BIN_DIR/tclConfig.sh... $ECHO_C" >&6 - if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then - echo "$as_me:$LINENO: result: loading" >&5 -echo "${ECHO_T}loading" >&6 - . $TCL_BIN_DIR/tclConfig.sh - else - echo "$as_me:$LINENO: result: file not found" >&5 -echo "${ECHO_T}file not found" >&6 - fi - - # - # If the TCL_BIN_DIR is the build directory (not the install directory), - # then set the common variable name to the value of the build variables. - # For example, the variable TCL_LIB_SPEC will be set to the value - # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC - # instead of TCL_BUILD_LIB_SPEC since it will work with both an - # installed and uninstalled version of Tcl. - # - - if test -f $TCL_BIN_DIR/Makefile ; then - TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} - TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} - TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} - fi - - # - # eval is required to do the TCL_DBGX substitution - # - - eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" - eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" - eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" - - eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" - eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" - eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" - - - - - - - - - - - - - - - fi -fi -if test "${use_tcl}" = "no" ; then - HAVE_TCL="" -else - HAVE_TCL=1 -fi - - -########## -# Figure out what C libraries are required to compile programs -# that use "readline()" library. -# -if test "$config_TARGET_READLINE_LIBS" != ""; then - TARGET_READLINE_LIBS="$config_TARGET_READLINE_LIBS" -else - CC=$TARGET_CC - LIBS="" - echo "$as_me:$LINENO: checking for library containing tgetent" >&5 -echo $ECHO_N "checking for library containing tgetent... $ECHO_C" >&6 -if test "${ac_cv_search_tgetent+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -ac_cv_search_tgetent=no -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char tgetent (); -int -main () -{ -tgetent (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_tgetent="none required" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_tgetent" = no; then - for ac_lib in readline ncurses curses termcap; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char tgetent (); -int -main () -{ -tgetent (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_tgetent="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - done -fi -LIBS=$ac_func_search_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_search_tgetent" >&5 -echo "${ECHO_T}$ac_cv_search_tgetent" >&6 -if test "$ac_cv_search_tgetent" != no; then - test "$ac_cv_search_tgetent" = "none required" || LIBS="$ac_cv_search_tgetent $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for readline in -lreadline" >&5 -echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6 -if test "${ac_cv_lib_readline_readline+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char readline (); -int -main () -{ -readline (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_readline_readline=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_readline_readline=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5 -echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6 -if test $ac_cv_lib_readline_readline = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBREADLINE 1 -_ACEOF - - LIBS="-lreadline $LIBS" - -fi - - TARGET_READLINE_LIBS="$LIBS" -fi - - -########## -# Figure out where to get the READLINE header files. -# -echo "$as_me:$LINENO: checking readline header files" >&5 -echo $ECHO_N "checking readline header files... $ECHO_C" >&6 -found=no -if test "$config_TARGET_READLINE_INC" != ""; then - TARGET_READLINE_INC=$config_TARGET_READLINE_INC - found=yes -fi -if test "$found" = "yes"; then - echo "$as_me:$LINENO: result: $TARGET_READLINE_INC" >&5 -echo "${ECHO_T}$TARGET_READLINE_INC" >&6 -else - echo "$as_me:$LINENO: result: not specified: still searching..." >&5 -echo "${ECHO_T}not specified: still searching..." >&6 - if test "${ac_cv_header_readline_h+set}" = set; then - echo "$as_me:$LINENO: checking for readline.h" >&5 -echo $ECHO_N "checking for readline.h... $ECHO_C" >&6 -if test "${ac_cv_header_readline_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_readline_h" >&5 -echo "${ECHO_T}$ac_cv_header_readline_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking readline.h usability" >&5 -echo $ECHO_N "checking readline.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking readline.h presence" >&5 -echo $ECHO_N "checking readline.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: readline.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: readline.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: readline.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: readline.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: readline.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: readline.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: readline.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: readline.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: readline.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: readline.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: readline.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: readline.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: readline.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: readline.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: readline.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: readline.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------------ ## -## Report this to the AC_PACKAGE_NAME lists. ## -## ------------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for readline.h" >&5 -echo $ECHO_N "checking for readline.h... $ECHO_C" >&6 -if test "${ac_cv_header_readline_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_readline_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_readline_h" >&5 -echo "${ECHO_T}$ac_cv_header_readline_h" >&6 - -fi -if test $ac_cv_header_readline_h = yes; then - found=yes -fi - - -fi -if test "$found" = "no"; then - for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do - as_ac_File=`echo "ac_cv_file_$dir/include/readline.h" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $dir/include/readline.h" >&5 -echo $ECHO_N "checking for $dir/include/readline.h... $ECHO_C" >&6 -if eval "test \"\${$as_ac_File+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - test "$cross_compiling" = yes && - { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 -echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} - { (exit 1); exit 1; }; } -if test -r "$dir/include/readline.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_File'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_File'}'`" >&6 -if test `eval echo '${'$as_ac_File'}'` = yes; then - found=yes -fi - - if test "$found" = "yes"; then - TARGET_READLINE_INC="-I$dir/include" - break - fi - as_ac_File=`echo "ac_cv_file_$dir/include/readline/readline.h" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $dir/include/readline/readline.h" >&5 -echo $ECHO_N "checking for $dir/include/readline/readline.h... $ECHO_C" >&6 -if eval "test \"\${$as_ac_File+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - test "$cross_compiling" = yes && - { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 -echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} - { (exit 1); exit 1; }; } -if test -r "$dir/include/readline/readline.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_File'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_File'}'`" >&6 -if test `eval echo '${'$as_ac_File'}'` = yes; then - found=yes -fi - - if test "$found" = "yes"; then - TARGET_READLINE_INC="-I$dir/include/readline" - break - fi - done -fi -if test "$found" = "yes"; then - if test "$TARGET_READLINE_LIBS" = ""; then - TARGET_HAVE_READLINE=0 - else - TARGET_HAVE_READLINE=1 - fi -else - TARGET_HAVE_READLINE=0 -fi - - - -######### -# check for debug enabled -# Check whether --enable-debug or --disable-debug was given. -if test "${enable_debug+set}" = set; then - enableval="$enable_debug" - use_debug=$enableval -else - use_debug=no -fi; -if test "${use_debug}" = "yes" ; then - TARGET_DEBUG="" -else - TARGET_DEBUG="-DNDEBUG" -fi - - -######### -# Figure out whether or not we have a "usleep()" function. -# -echo "$as_me:$LINENO: checking for usleep" >&5 -echo $ECHO_N "checking for usleep... $ECHO_C" >&6 -if test "${ac_cv_func_usleep+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define usleep to an innocuous variant, in case declares usleep. - For example, HP-UX 11i declares gettimeofday. */ -#define usleep innocuous_usleep - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char usleep (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef usleep - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char usleep (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_usleep) || defined (__stub___usleep) -choke me -#else -char (*f) () = usleep; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != usleep; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_usleep=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_usleep=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_usleep" >&5 -echo "${ECHO_T}$ac_cv_func_usleep" >&6 -if test $ac_cv_func_usleep = yes; then - TARGET_CFLAGS="$TARGET_CFLAGS -DHAVE_USLEEP=1" -fi - - -######### -# Generate the output files. -# - ac_config_files="$ac_config_files Makefile sqlite3.pc" -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -{ - (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} | - sed ' - t clear - : clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if diff $cache_file confcache >/dev/null 2>&1; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" - cat confcache >$cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then we branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -cat >confdef2opt.sed <<\_ACEOF -t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g -t quote -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g -t quote -d -: quote -s,[ `~#$^&*(){}\\|;'"<>?],\\&,g -s,\[,\\&,g -s,\],\\&,g -s,\$,$$,g -p -_ACEOF -# We use echo to avoid assuming a particular line-breaking character. -# The extra dot is to prevent the shell from consuming trailing -# line-breaks from the sub-command output. A line-break within -# single-quotes doesn't work because, if this script is created in a -# platform that uses two characters for line-breaks (e.g., DOS), tr -# would break. -ac_LF_and_DOT=`echo; echo .` -DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` -rm -f confdef2opt.sed - - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_i=`echo "$ac_i" | - sed 's/\$U\././;s/\.o$//;s/\.obj$//'` - # 2. Add them. - ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi -DUALCASE=1; export DUALCASE # for MKS sh - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - -exec 6>&1 - -# Open the log real soon, to keep \$[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - -This file was extended by $as_me, which was -generated by GNU Autoconf 2.59. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 -_ACEOF - -# Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi - -cat >>$CONFIG_STATUS <<\_ACEOF - -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Report bugs to ." -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.59, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2003 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir -INSTALL="$INSTALL" -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` - ac_shift=: - ;; - -*) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_option=$1 - ac_need_defaults=false;; - esac - - case $ac_option in - # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" - ac_need_defaults=false;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -if \$ac_cs_recheck; then - echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion -fi - -_ACEOF - - - - - -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_config_target in $ac_config_targets -do - case "$ac_config_target" in - # Handling of arguments. - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "sqlite3.pc" ) CONFIG_FILES="$CONFIG_FILES sqlite3.pc" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason to put it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Create a temporary directory, and hook for its removal unless debugging. -$debug || -{ - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} - -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./confstat$$-$RANDOM - (umask 077 && mkdir $tmp) -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF - -# -# CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@build@,$build,;t t -s,@build_cpu@,$build_cpu,;t t -s,@build_vendor@,$build_vendor,;t t -s,@build_os@,$build_os,;t t -s,@host@,$host,;t t -s,@host_cpu@,$host_cpu,;t t -s,@host_vendor@,$host_vendor,;t t -s,@host_os@,$host_os,;t t -s,@CC@,$CC,;t t -s,@CFLAGS@,$CFLAGS,;t t -s,@LDFLAGS@,$LDFLAGS,;t t -s,@CPPFLAGS@,$CPPFLAGS,;t t -s,@ac_ct_CC@,$ac_ct_CC,;t t -s,@EXEEXT@,$EXEEXT,;t t -s,@OBJEXT@,$OBJEXT,;t t -s,@EGREP@,$EGREP,;t t -s,@LN_S@,$LN_S,;t t -s,@ECHO@,$ECHO,;t t -s,@AR@,$AR,;t t -s,@ac_ct_AR@,$ac_ct_AR,;t t -s,@RANLIB@,$RANLIB,;t t -s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t -s,@STRIP@,$STRIP,;t t -s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t -s,@CPP@,$CPP,;t t -s,@CXX@,$CXX,;t t -s,@CXXFLAGS@,$CXXFLAGS,;t t -s,@ac_ct_CXX@,$ac_ct_CXX,;t t -s,@CXXCPP@,$CXXCPP,;t t -s,@F77@,$F77,;t t -s,@FFLAGS@,$FFLAGS,;t t -s,@ac_ct_F77@,$ac_ct_F77,;t t -s,@LIBTOOL@,$LIBTOOL,;t t -s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t -s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t -s,@INSTALL_DATA@,$INSTALL_DATA,;t t -s,@program_prefix@,$program_prefix,;t t -s,@VERSION@,$VERSION,;t t -s,@VERSION_NUMBER@,$VERSION_NUMBER,;t t -s,@RELEASE@,$RELEASE,;t t -s,@BUILD_CC@,$BUILD_CC,;t t -s,@BUILD_CFLAGS@,$BUILD_CFLAGS,;t t -s,@BUILD_LIBS@,$BUILD_LIBS,;t t -s,@TARGET_CC@,$TARGET_CC,;t t -s,@TARGET_CFLAGS@,$TARGET_CFLAGS,;t t -s,@TARGET_LINK@,$TARGET_LINK,;t t -s,@TARGET_LFLAGS@,$TARGET_LFLAGS,;t t -s,@TARGET_RANLIB@,$TARGET_RANLIB,;t t -s,@TARGET_AR@,$TARGET_AR,;t t -s,@THREADSAFE@,$THREADSAFE,;t t -s,@TARGET_THREAD_LIB@,$TARGET_THREAD_LIB,;t t -s,@ALLOWRELEASE@,$ALLOWRELEASE,;t t -s,@TEMP_STORE@,$TEMP_STORE,;t t -s,@BUILD_EXEEXT@,$BUILD_EXEEXT,;t t -s,@OS_UNIX@,$OS_UNIX,;t t -s,@OS_WIN@,$OS_WIN,;t t -s,@TARGET_EXEEXT@,$TARGET_EXEEXT,;t t -s,@TARGET_LIBS@,$TARGET_LIBS,;t t -s,@TCL_VERSION@,$TCL_VERSION,;t t -s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t -s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t -s,@TCL_LIBS@,$TCL_LIBS,;t t -s,@TCL_INCLUDE_SPEC@,$TCL_INCLUDE_SPEC,;t t -s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t -s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t -s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t -s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t -s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t -s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t -s,@HAVE_TCL@,$HAVE_TCL,;t t -s,@TARGET_READLINE_LIBS@,$TARGET_READLINE_LIBS,;t t -s,@TARGET_READLINE_INC@,$TARGET_READLINE_INC,;t t -s,@TARGET_HAVE_READLINE@,$TARGET_HAVE_READLINE,;t t -s,@TARGET_DEBUG@,$TARGET_DEBUG,;t t -s,@LIBOBJS@,$LIBOBJS,;t t -s,@LTLIBOBJS@,$LTLIBOBJS,;t t -CEOF - -_ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` - fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat - fi -fi # test -n "$CONFIG_FILES" - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; - esac - - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_builddir$INSTALL ;; - esac - - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -s,@INSTALL@,$ac_INSTALL,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi - -done -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi - diff --git a/sqlite/configure.ac b/sqlite/configure.ac deleted file mode 100644 index 8f2ea96..0000000 --- a/sqlite/configure.ac +++ /dev/null @@ -1,611 +0,0 @@ -# -# The build process allows for using a cross-compiler. But the default -# action is to target the same platform that we are running on. The -# configure script needs to discover the following properties of the -# build and target systems: -# -# srcdir -# -# The is the name of the directory that contains the -# "configure" shell script. All source files are -# located relative to this directory. -# -# bindir -# -# The name of the directory where executables should be -# written by the "install" target of the makefile. -# -# program_prefix -# -# Add this prefix to the names of all executables that run -# on the target machine. Default: "" -# -# ENABLE_SHARED -# -# True if shared libraries should be generated. -# -# BUILD_CC -# -# The name of a command that is used to convert C -# source files into executables that run on the build -# platform. -# -# BUILD_CFLAGS -# -# Switches that the build compiler needs in order to construct -# command-line programs. -# -# BUILD_LIBS -# -# Libraries that the build compiler needs in order to construct -# command-line programs. -# -# BUILD_EXEEXT -# -# The filename extension for executables on the build -# platform. "" for Unix and ".exe" for Windows. -# -# TARGET_CC -# -# The name of a command that runs on the build platform -# and converts C source files into *.o files for the -# target platform. In other words, the cross-compiler. -# -# TARGET_CFLAGS -# -# Switches that the target compiler needs to turn C source files -# into *.o files. Do not include TARGET_TCL_INC in this list. -# Makefiles might add additional switches such as "-I.". -# -# TCL_* -# -# Lots of values are read in from the tclConfig.sh script, -# if that script is available. This values are used for -# constructing and installing the TCL extension. -# -# TARGET_READLINE_LIBS -# -# This is the library directives passed to the target linker -# that cause the executable to link against the readline library. -# This might be a switch like "-lreadline" or pathnames of library -# file like "../../src/libreadline.a". -# -# TARGET_READLINE_INC -# -# This variables define the directory that contain header -# files for the readline library. If the compiler is able -# to find on its own, then this can be blank. -# -# TARGET_LINK -# -# The name of the linker that combines *.o files generated -# by TARGET_CC into executables for the target platform. -# -# TARGET_LIBS -# -# Additional libraries or other switch that the target linker needs -# to build an executable on the target. Do not include -# on this list any libraries in TARGET_TCL_LIBS and -# TARGET_READLINE_LIBS, etc. -# -# TARGET_EXEEXT -# -# The filename extension for executables on the -# target platform. "" for Unix and ".exe" for windows. -# -# The generated configure script will make an attempt to guess -# at all of the above parameters. You can override any of -# the guesses by setting the environment variable named -# "config_AAAA" where "AAAA" is the name of the parameter -# described above. (Exception: srcdir cannot be set this way.) -# If you have a file that sets one or more of these environment -# variables, you can invoke configure as follows: -# -# configure --with-hints=FILE -# -# where FILE is the name of the file that sets the environment -# variables. FILE should be an absolute pathname. -# -# This configure.in file is easy to reuse on other projects. Just -# change the argument to AC_INIT(). And disable any features that -# you don't need (for example BLT) by erasing or commenting out -# the corresponding code. -# -AC_INIT(src/sqlite.h.in) - -dnl Put the RCS revision string after AC_INIT so that it will also -dnl show in in configure. -# The following RCS revision string applies to configure.in -# $Revision: 1.15 $ - -######### -# Programs needed -# -AC_PROG_LIBTOOL -AC_PROG_INSTALL - -######### -# Set up an appropriate program prefix -# -if test "$program_prefix" = "NONE"; then - program_prefix="" -fi -AC_SUBST(program_prefix) - -VERSION=[`cat $srcdir/VERSION | sed 's/^\([0-9]*\.*[0-9]*\).*/\1/'`] -echo "Version set to $VERSION" -AC_SUBST(VERSION) -RELEASE=`cat $srcdir/VERSION` -echo "Release set to $RELEASE" -AC_SUBST(RELEASE) - -######### -# Check to see if the --with-hints=FILE option is used. If there is none, -# then check for a files named "$host.hints" and ../$hosts.hints where -# $host is the hostname of the build system. If still no hints are -# found, try looking in $system.hints and ../$system.hints where -# $system is the result of uname -s. -# -AC_ARG_WITH(hints, - [ --with-hints=FILE Read configuration options from FILE], - hints=$withval) -if test "$hints" = ""; then - host=`hostname | sed 's/\..*//'` - if test -r $host.hints; then - hints=$host.hints - else - if test -r ../$host.hints; then - hints=../$host.hints - fi - fi -fi -if test "$hints" = ""; then - sys=`uname -s` - if test -r $sys.hints; then - hints=$sys.hints - else - if test -r ../$sys.hints; then - hints=../$sys.hints - fi - fi -fi -if test "$hints" != ""; then - AC_MSG_RESULT(reading hints from $hints) - . $hints -fi - -######### -# Locate a compiler for the build machine. This compiler should -# generate command-line programs that run on the build machine. -# -default_build_cflags="-g" -if test "$config_BUILD_CC" = ""; then - AC_PROG_CC - if test "$cross_compiling" = "yes"; then - AC_MSG_ERROR([unable to find a compiler for building build tools]) - fi - BUILD_CC=$CC - default_build_cflags=$CFLAGS -else - BUILD_CC=$config_BUILD_CC - AC_MSG_CHECKING([host compiler]) - CC=$BUILD_CC - AC_MSG_RESULT($BUILD_CC) -fi -AC_MSG_CHECKING([switches for the host compiler]) -if test "$config_BUILD_CFLAGS" != ""; then - CFLAGS=$config_BUILD_CFLAGS - BUILD_CFLAGS=$config_BUILD_CFLAGS -else - BUILD_CFLAGS=$default_build_cflags -fi -AC_MSG_RESULT($BUILD_CFLAGS) -if test "$config_BUILD_LIBS" != ""; then - BUILD_LIBS=$config_BUILD_LIBS -fi -AC_SUBST(BUILD_CC) -AC_SUBST(BUILD_CFLAGS) -AC_SUBST(BUILD_LIBS) - -########## -# Locate a compiler that converts C code into *.o files that run on -# the target machine. -# -AC_MSG_CHECKING([target compiler]) -if test "$config_TARGET_CC" != ""; then - TARGET_CC=$config_TARGET_CC -else - TARGET_CC=$BUILD_CC -fi -AC_MSG_RESULT($TARGET_CC) -AC_MSG_CHECKING([switches on the target compiler]) -if test "$config_TARGET_CFLAGS" != ""; then - TARGET_CFLAGS=$config_TARGET_CFLAGS -else - TARGET_CFLAGS=$BUILD_CFLAGS -fi -AC_MSG_RESULT($TARGET_CFLAGS) -AC_MSG_CHECKING([target linker]) -if test "$config_TARGET_LINK" = ""; then - TARGET_LINK=$TARGET_CC -else - TARGET_LINK=$config_TARGET_LINK -fi -AC_MSG_RESULT($TARGET_LINK) -AC_MSG_CHECKING([switches on the target compiler]) -if test "$config_TARGET_TFLAGS" != ""; then - TARGET_TFLAGS=$config_TARGET_TFLAGS -else - TARGET_TFLAGS=$BUILD_CFLAGS -fi -if test "$config_TARGET_RANLIB" != ""; then - TARGET_RANLIB=$config_TARGET_RANLIB -else - AC_PROG_RANLIB - TARGET_RANLIB=$RANLIB -fi -if test "$config_TARGET_AR" != ""; then - TARGET_AR=$config_TARGET_AR -else - TARGET_AR='ar cr' -fi -AC_MSG_RESULT($TARGET_TFLAGS) -AC_SUBST(TARGET_CC) -AC_SUBST(TARGET_CFLAGS) -AC_SUBST(TARGET_LINK) -AC_SUBST(TARGET_LFLAGS) -AC_SUBST(TARGET_RANLIB) -AC_SUBST(TARGET_AR) - -# Set the $cross variable if we are cross-compiling. Make -# it 0 if we are not. -# -AC_MSG_CHECKING([if host and target compilers are the same]) -if test "$BUILD_CC" = "$TARGET_CC"; then - cross=0 - AC_MSG_RESULT(yes) -else - cross=1 - AC_MSG_RESULT(no) -fi - -########## -# Do we want to support multithreaded use of sqlite -# -AC_ARG_ENABLE(threadsafe, -[ --enable-threadsafe Support threadsafe operation],,enable_threadsafe=no) -AC_MSG_CHECKING([whether to support threadsafe operation]) -if test "$enable_threadsafe" = "no"; then - THREADSAFE=0 - AC_MSG_RESULT([no]) -else - THREADSAFE=1 - AC_MSG_RESULT([yes]) -fi -AC_SUBST(THREADSAFE) - -if test "$THREADSAFE" = "1"; then - LIBS="" - AC_CHECK_LIB(pthread, pthread_create) - TARGET_THREAD_LIB="$LIBS" - LIBS="" -else - TARGET_THREAD_LIB="" -fi -AC_SUBST(TARGET_THREAD_LIB) - -########## -# Do we want to support release -# -AC_ARG_ENABLE(releasemode, -[ --enable-releasemode Support libtool link to release mode],,enable_releasemode=no) -AC_MSG_CHECKING([whether to support shared library linked as release mode or not]) -if test "$enable_releasemode" = "no"; then - ALLOWRELEASE="" - AC_MSG_RESULT([no]) -else - ALLOWRELEASE="-release `cat VERSION`" - AC_MSG_RESULT([yes]) -fi -AC_SUBST(ALLOWRELEASE) - -########## -# Do we want temporary databases in memory -# -AC_ARG_ENABLE(tempstore, -[ --enable-tempstore Use an in-ram database for temporary tables (never,no,yes,always)],,enable_tempstore=yes) -AC_MSG_CHECKING([whether to use an in-ram database for temporary tables]) -case "$enable_tempstore" in - never ) - TEMP_STORE=0 - AC_MSG_RESULT([never]) - ;; - no ) - TEMP_STORE=1 - AC_MSG_RESULT([no]) - ;; - always ) - TEMP_STORE=3 - AC_MSG_RESULT([always]) - ;; - * ) - TEMP_STORE=2 - AC_MSG_RESULT([yes]) - ;; -esac - -AC_SUBST(TEMP_STORE) - -########### -# Lots of things are different if we are compiling for Windows using -# the CYGWIN environment. So check for that special case and handle -# things accordingly. -# -AC_MSG_CHECKING([if executables have the .exe suffix]) -if test "$config_BUILD_EXEEXT" = ".exe"; then - CYGWIN=yes - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(unknown) -fi -if test "$CYGWIN" != "yes"; then - AC_CYGWIN -fi -if test "$CYGWIN" = "yes"; then - BUILD_EXEEXT=.exe -else - BUILD_EXEEXT=$EXEEXT -fi -if test "$cross" = "0"; then - TARGET_EXEEXT=$BUILD_EXEEXT -else - TARGET_EXEEXT=$config_TARGET_EXEEXT -fi -if test "$TARGET_EXEEXT" = ".exe"; then - OS_UNIX=0 - OS_WIN=1 - tclsubdir=win - TARGET_CFLAGS="$TARGET_CFLAGS -DOS_WIN=1" -else - OS_UNIX=1 - OS_WIN=0 - tclsubdir=unix - TARGET_CFLAGS="$TARGET_CFLAGS -DOS_UNIX=1" -fi - -AC_SUBST(BUILD_EXEEXT) -AC_SUBST(OS_UNIX) -AC_SUBST(OS_WIN) -AC_SUBST(TARGET_EXEEXT) - -########## -# Extract generic linker options from the environment. -# -if test "$config_TARGET_LIBS" != ""; then - TARGET_LIBS=$config_TARGET_LIBS -else - TARGET_LIBS="" -fi -AC_SUBST(TARGET_LIBS) - -########## -# Figure out all the parameters needed to compile against Tcl. -# -# This code is derived from the SC_PATH_TCLCONFIG and SC_LOAD_TCLCONFIG -# macros in the in the tcl.m4 file of the standard TCL distribution. -# Those macros could not be used directly since we have to make some -# minor changes to accomodate systems that do not have TCL installed. -# -AC_ARG_ENABLE(tcl, [ --disable-tcl do not build TCL extension], - [use_tcl=$enableval],[use_tcl=yes]) -if test "${use_tcl}" = "yes" ; then - AC_ARG_WITH(tcl, [ --with-tcl=DIR directory containing tcl configuration (tclConfig.sh)], with_tclconfig=${withval}) - AC_MSG_CHECKING([for Tcl configuration]) - AC_CACHE_VAL(ac_cv_c_tclconfig,[ - # First check to see if --with-tcl was specified. - if test x"${with_tclconfig}" != x ; then - if test -f "${with_tclconfig}/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` - else - AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) - fi - fi - # then check for a private Tcl installation - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ../tcl \ - `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ - ../../tcl \ - `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ - ../../../tcl \ - `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` - do - if test -f "$i/unix/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i/unix; pwd)` - break - fi - done - fi - - # check in a few common install locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - `ls -d ${libdir} 2>/dev/null` \ - `ls -d /usr/local/lib 2>/dev/null` \ - `ls -d /usr/contrib/lib 2>/dev/null` \ - `ls -d /usr/lib 2>/dev/null` - do - if test -f "$i/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i; pwd)` - break - fi - done - fi - - # check in a few other private locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ${srcdir}/../tcl \ - `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` - do - if test -f "$i/unix/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i/unix; pwd)` - break - fi - done - fi - ]) - - if test x"${ac_cv_c_tclconfig}" = x ; then - use_tcl=no - AC_MSG_WARN(Can't find Tcl configuration definitions) - AC_MSG_WARN(*** Without Tcl the regression tests cannot be executed ***) - AC_MSG_WARN(*** Consider using --with-tcl=... to define location of Tcl ***) - else - TCL_BIN_DIR=${ac_cv_c_tclconfig} - AC_MSG_RESULT(found $TCL_BIN_DIR/tclConfig.sh) - - AC_MSG_CHECKING([for existence of $TCL_BIN_DIR/tclConfig.sh]) - if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then - AC_MSG_RESULT([loading]) - . $TCL_BIN_DIR/tclConfig.sh - else - AC_MSG_RESULT([file not found]) - fi - - # - # If the TCL_BIN_DIR is the build directory (not the install directory), - # then set the common variable name to the value of the build variables. - # For example, the variable TCL_LIB_SPEC will be set to the value - # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC - # instead of TCL_BUILD_LIB_SPEC since it will work with both an - # installed and uninstalled version of Tcl. - # - - if test -f $TCL_BIN_DIR/Makefile ; then - TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} - TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} - TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} - fi - - # - # eval is required to do the TCL_DBGX substitution - # - - eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" - eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" - eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" - - eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" - eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" - eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" - - AC_SUBST(TCL_VERSION) - AC_SUBST(TCL_BIN_DIR) - AC_SUBST(TCL_SRC_DIR) - AC_SUBST(TCL_LIBS) - AC_SUBST(TCL_INCLUDE_SPEC) - - AC_SUBST(TCL_LIB_FILE) - AC_SUBST(TCL_LIB_FLAG) - AC_SUBST(TCL_LIB_SPEC) - - AC_SUBST(TCL_STUB_LIB_FILE) - AC_SUBST(TCL_STUB_LIB_FLAG) - AC_SUBST(TCL_STUB_LIB_SPEC) - fi -fi -if test "${use_tcl}" = "no" ; then - HAVE_TCL="" -else - HAVE_TCL=1 -fi -AC_SUBST(HAVE_TCL) - -########## -# Figure out what C libraries are required to compile programs -# that use "readline()" library. -# -if test "$config_TARGET_READLINE_LIBS" != ""; then - TARGET_READLINE_LIBS="$config_TARGET_READLINE_LIBS" -else - CC=$TARGET_CC - LIBS="" - AC_SEARCH_LIBS(tgetent, [readline ncurses curses termcap]) - AC_CHECK_LIB([readline], [readline]) - TARGET_READLINE_LIBS="$LIBS" -fi -AC_SUBST(TARGET_READLINE_LIBS) - -########## -# Figure out where to get the READLINE header files. -# -AC_MSG_CHECKING([readline header files]) -found=no -if test "$config_TARGET_READLINE_INC" != ""; then - TARGET_READLINE_INC=$config_TARGET_READLINE_INC - found=yes -fi -if test "$found" = "yes"; then - AC_MSG_RESULT($TARGET_READLINE_INC) -else - AC_MSG_RESULT(not specified: still searching...) - AC_CHECK_HEADER(readline.h, [found=yes]) -fi -if test "$found" = "no"; then - for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do - AC_CHECK_FILE($dir/include/readline.h, found=yes) - if test "$found" = "yes"; then - TARGET_READLINE_INC="-I$dir/include" - break - fi - AC_CHECK_FILE($dir/include/readline/readline.h, found=yes) - if test "$found" = "yes"; then - TARGET_READLINE_INC="-I$dir/include/readline" - break - fi - done -fi -if test "$found" = "yes"; then - if test "$TARGET_READLINE_LIBS" = ""; then - TARGET_HAVE_READLINE=0 - else - TARGET_HAVE_READLINE=1 - fi -else - TARGET_HAVE_READLINE=0 -fi -AC_SUBST(TARGET_READLINE_INC) -AC_SUBST(TARGET_HAVE_READLINE) - -######### -# check for debug enabled -AC_ARG_ENABLE(debug, [ --enable-debug enable debugging & verbose explain], - [use_debug=$enableval],[use_debug=no]) -if test "${use_debug}" = "yes" ; then - TARGET_DEBUG="" -else - TARGET_DEBUG="-DNDEBUG" -fi -AC_SUBST(TARGET_DEBUG) - -######### -# Figure out whether or not we have a "usleep()" function. -# -AC_CHECK_FUNC(usleep, [TARGET_CFLAGS="$TARGET_CFLAGS -DHAVE_USLEEP=1"]) - -######### -# Generate the output files. -# -AC_OUTPUT([ -Makefile -sqlite3.pc -]) diff --git a/sqlite/main.mk b/sqlite/main.mk deleted file mode 100644 index 6f0fcac..0000000 --- a/sqlite/main.mk +++ /dev/null @@ -1,548 +0,0 @@ -############################################################################### -# The following macros should be defined before this script is -# invoked: -# -# TOP The toplevel directory of the source tree. This is the -# directory that contains this "Makefile.in" and the -# "configure.in" script. -# -# BCC C Compiler and options for use in building executables that -# will run on the platform that is doing the build. -# -# USLEEP If the target operating system supports the "usleep()" system -# call, then define the HAVE_USLEEP macro for all C modules. -# -# THREADSAFE If you want the SQLite library to be safe for use within a -# multi-threaded program, then define the following macro -# appropriately: -# -# THREADLIB Specify any extra linker options needed to make the library -# thread safe -# -# OPTS Extra compiler command-line options. -# -# EXE The suffix to add to executable files. ".exe" for windows -# and "" for Unix. -# -# TCC C Compiler and options for use in building executables that -# will run on the target platform. This is usually the same -# as BCC, unless you are cross-compiling. -# -# AR Tools used to build a static library. -# RANLIB -# -# TCL_FLAGS Extra compiler options needed for programs that use the -# TCL library. -# -# LIBTCL Linker options needed to link against the TCL library. -# -# READLINE_FLAGS Compiler options needed for programs that use the -# readline() library. -# -# LIBREADLINE Linker options needed by programs using readline() must -# link against. -# -# ENCODING "UTF8" or "ISO8859" -# -# Once the macros above are defined, the rest of this make script will -# build the SQLite library and testing tools. -################################################################################ - -# This is how we compile -# -TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src - -# Object files for the SQLite library. -# -LIBOBJ+= attach.o auth.o btree.o build.o date.o delete.o \ - expr.o func.o hash.o insert.o \ - main.o opcodes.o os_unix.o os_win.o \ - pager.o parse.o pragma.o printf.o random.o \ - select.o table.o tclsqlite.o tokenize.o trigger.o \ - update.o util.o vacuum.o \ - vdbe.o vdbeapi.o vdbeaux.o vdbemem.o \ - where.o utf.o legacy.o - -# All of the source code files. -# -SRC = \ - $(TOP)/src/attach.c \ - $(TOP)/src/auth.c \ - $(TOP)/src/btree.c \ - $(TOP)/src/btree.h \ - $(TOP)/src/build.c \ - $(TOP)/src/date.c \ - $(TOP)/src/delete.c \ - $(TOP)/src/expr.c \ - $(TOP)/src/func.c \ - $(TOP)/src/hash.c \ - $(TOP)/src/hash.h \ - $(TOP)/src/insert.c \ - $(TOP)/src/legacy.c \ - $(TOP)/src/main.c \ - $(TOP)/src/os_unix.c \ - $(TOP)/src/os_win.c \ - $(TOP)/src/pager.c \ - $(TOP)/src/pager.h \ - $(TOP)/src/parse.y \ - $(TOP)/src/pragma.c \ - $(TOP)/src/printf.c \ - $(TOP)/src/random.c \ - $(TOP)/src/select.c \ - $(TOP)/src/shell.c \ - $(TOP)/src/sqlite.h.in \ - $(TOP)/src/sqliteInt.h \ - $(TOP)/src/table.c \ - $(TOP)/src/tclsqlite.c \ - $(TOP)/src/tokenize.c \ - $(TOP)/src/trigger.c \ - $(TOP)/src/utf.c \ - $(TOP)/src/update.c \ - $(TOP)/src/util.c \ - $(TOP)/src/vacuum.c \ - $(TOP)/src/vdbe.c \ - $(TOP)/src/vdbe.h \ - $(TOP)/src/vdbeapi.c \ - $(TOP)/src/vdbeaux.c \ - $(TOP)/src/vdbemem.c \ - $(TOP)/src/vdbeInt.h \ - $(TOP)/src/where.c - -# Source code to the test files. -# -TESTSRC = \ - $(TOP)/src/btree.c \ - $(TOP)/src/date.c \ - $(TOP)/src/func.c \ - $(TOP)/src/os_unix.c \ - $(TOP)/src/os_win.c \ - $(TOP)/src/pager.c \ - $(TOP)/src/pragma.c \ - $(TOP)/src/printf.c \ - $(TOP)/src/test1.c \ - $(TOP)/src/test2.c \ - $(TOP)/src/test3.c \ - $(TOP)/src/test4.c \ - $(TOP)/src/test5.c \ - $(TOP)/src/utf.c \ - $(TOP)/src/util.c \ - $(TOP)/src/vdbe.c \ - $(TOP)/src/md5.c - -# Header files used by all library source files. -# -HDR = \ - sqlite3.h \ - $(TOP)/src/btree.h \ - config.h \ - $(TOP)/src/hash.h \ - opcodes.h \ - $(TOP)/src/os.h \ - $(TOP)/src/os_common.h \ - $(TOP)/src/os_unix.h \ - $(TOP)/src/os_win.h \ - $(TOP)/src/sqliteInt.h \ - $(TOP)/src/vdbe.h \ - parse.h - -# Header files used by the VDBE submodule -# -VDBEHDR = \ - $(HDR) \ - $(TOP)/src/vdbeInt.h - -# This is the default Makefile target. The objects listed here -# are what get build when you type just "make" with no arguments. -# -all: sqlite3.h config.h libsqlite3.a sqlite3$(EXE) - -# Generate the file "last_change" which contains the date of change -# of the most recently modified source code file -# -last_change: $(SRC) - cat $(SRC) | grep '$$Id: ' | sort +4 | tail -1 \ - | awk '{print $$5,$$6}' >last_change - -libsqlite3.a: $(LIBOBJ) - $(AR) libsqlite3.a $(LIBOBJ) - $(RANLIB) libsqlite3.a - -sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h - $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(TOP)/src/shell.c \ - libsqlite3.a $(LIBREADLINE) $(THREADLIB) - -objects: $(LIBOBJ_ORIG) - -# This target creates a directory named "tsrc" and fills it with -# copies of all of the C source code and header files needed to -# build on the target system. Some of the C source code and header -# files are automatically generated. This target takes care of -# all that automatic generation. -# -target_source: $(SRC) $(VDBEHDR) opcodes.c keywordhash.h - rm -rf tsrc - mkdir tsrc - cp $(SRC) $(VDBEHDR) tsrc - rm tsrc/sqlite.h.in tsrc/parse.y - cp parse.c opcodes.c keywordhash.h tsrc - cp $(TOP)/sqlite3.def tsrc - -# Rules to build the LEMON compiler generator -# -lemon: $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c - $(BCC) -o lemon $(TOP)/tool/lemon.c - cp $(TOP)/tool/lempar.c . - -# Rules to build individual files -# -attach.o: $(TOP)/src/attach.c $(HDR) - $(TCCX) -c $(TOP)/src/attach.c - -auth.o: $(TOP)/src/auth.c $(HDR) - $(TCCX) -c $(TOP)/src/auth.c - -btree.o: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h - $(TCCX) -c $(TOP)/src/btree.c - -build.o: $(TOP)/src/build.c $(HDR) - $(TCCX) -c $(TOP)/src/build.c - -# The config.h file will contain a single #define that tells us how -# many bytes are in a pointer. This only works if a pointer is the -# same size on the host as it is on the target. If you are cross-compiling -# to a target with a different pointer size, you'll need to manually -# configure the config.h file. -# -config.h: - echo '#include ' >temp.c - echo 'int main(){printf(' >>temp.c - echo '"#define SQLITE_PTR_SZ %d",sizeof(char*));' >>temp.c - echo 'exit(0);}' >>temp.c - $(BCC) -o temp temp.c - ./temp >config.h - echo >>config.h - rm -f temp.c temp - -date.o: $(TOP)/src/date.c $(HDR) - $(TCCX) -c $(TOP)/src/date.c - -delete.o: $(TOP)/src/delete.c $(HDR) - $(TCCX) -c $(TOP)/src/delete.c - -expr.o: $(TOP)/src/expr.c $(HDR) - $(TCCX) -c $(TOP)/src/expr.c - -func.o: $(TOP)/src/func.c $(HDR) - $(TCCX) -c $(TOP)/src/func.c - -hash.o: $(TOP)/src/hash.c $(HDR) - $(TCCX) -c $(TOP)/src/hash.c - -insert.o: $(TOP)/src/insert.c $(HDR) - $(TCCX) -c $(TOP)/src/insert.c - -legacy.o: $(TOP)/src/legacy.c $(HDR) - $(TCCX) -c $(TOP)/src/legacy.c - -main.o: $(TOP)/src/main.c $(HDR) - $(TCCX) -c $(TOP)/src/main.c - -pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h - $(TCCX) -c $(TOP)/src/pager.c - -opcodes.o: opcodes.c - $(TCCX) -c opcodes.c - -opcodes.c: opcodes.h $(TOP)/mkopcodec.awk - sort -n -b +2 opcodes.h | awk -f $(TOP)/mkopcodec.awk >opcodes.c - -opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk - cat parse.h $(TOP)/src/vdbe.c | awk -f $(TOP)/mkopcodeh.awk >opcodes.h - -os_unix.o: $(TOP)/src/os_unix.c $(HDR) - $(TCCX) -c $(TOP)/src/os_unix.c - -os_win.o: $(TOP)/src/os_win.c $(HDR) - $(TCCX) -c $(TOP)/src/os_win.c - -parse.o: parse.c $(HDR) - $(TCCX) -c parse.c - -parse.h: parse.c - -parse.c: $(TOP)/src/parse.y lemon - cp $(TOP)/src/parse.y . - ./lemon $(OPTS) parse.y - -pragma.o: $(TOP)/src/pragma.c $(HDR) - $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/pragma.c - -printf.o: $(TOP)/src/printf.c $(HDR) - $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/printf.c - -random.o: $(TOP)/src/random.c $(HDR) - $(TCCX) -c $(TOP)/src/random.c - -select.o: $(TOP)/src/select.c $(HDR) - $(TCCX) -c $(TOP)/src/select.c - -sqlite3.h: $(TOP)/src/sqlite.h.in - sed -e s/--VERS--/`cat ${TOP}/VERSION`/ \ - -e s/--VERSION-NUMBER--/`cat ${TOP}/VERSION | sed 's/[^0-9]/ /g' | awk '{printf "%d%03d%03d",$$1,$$2,$$3}'`/ \ - $(TOP)/src/sqlite.h.in >sqlite3.h - -table.o: $(TOP)/src/table.c $(HDR) - $(TCCX) -c $(TOP)/src/table.c - -tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) - $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c - -tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) - $(TCCX) -c $(TOP)/src/tokenize.c - -keywordhash.h: $(TOP)/tool/mkkeywordhash.c - $(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c - ./mkkeywordhash >keywordhash.h - -trigger.o: $(TOP)/src/trigger.c $(HDR) - $(TCCX) -c $(TOP)/src/trigger.c - -update.o: $(TOP)/src/update.c $(HDR) - $(TCCX) -c $(TOP)/src/update.c - -utf.o: $(TOP)/src/utf.c $(HDR) - $(TCCX) -c $(TOP)/src/utf.c - -util.o: $(TOP)/src/util.c $(HDR) - $(TCCX) -c $(TOP)/src/util.c - -vacuum.o: $(TOP)/src/vacuum.c $(HDR) - $(TCCX) -c $(TOP)/src/vacuum.c - -vdbe.o: $(TOP)/src/vdbe.c $(VDBEHDR) - $(TCCX) -c $(TOP)/src/vdbe.c - -vdbeapi.o: $(TOP)/src/vdbeapi.c $(VDBEHDR) - $(TCCX) -c $(TOP)/src/vdbeapi.c - -vdbeaux.o: $(TOP)/src/vdbeaux.c $(VDBEHDR) - $(TCCX) -c $(TOP)/src/vdbeaux.c - -vdbemem.o: $(TOP)/src/vdbemem.c $(VDBEHDR) - $(TCCX) -c $(TOP)/src/vdbemem.c - -where.o: $(TOP)/src/where.c $(HDR) - $(TCCX) -c $(TOP)/src/where.c - -# Rules for building test programs and for running tests -# -tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a - $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \ - $(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB) - -testfixture$(EXE): $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) - $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -DSQLITE_TEST=1 -o testfixture$(EXE) \ - $(TESTSRC) $(TOP)/src/tclsqlite.c \ - libsqlite3.a $(LIBTCL) $(THREADLIB) - -crashtest: $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TOP)/src/os_test.c - $(TCCX) $(TCL_FLAGS) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 \ - -o crashtest \ - $(TESTSRC) $(TOP)/src/os_test.c $(TOP)/src/tclsqlite.c \ - libsqlite3.a $(LIBTCL) $(THREADLIB) - -fulltest: testfixture$(EXE) sqlite3$(EXE) crashtest - ./testfixture$(EXE) $(TOP)/test/all.test - -test: testfixture$(EXE) sqlite3$(EXE) - ./testfixture$(EXE) $(TOP)/test/quick.test - -sqlite3_analyzer$(EXE): $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) \ - $(TOP)/tool/spaceanal.tcl - sed \ - -e '/^#/d' \ - -e 's,\\,\\\\,g' \ - -e 's,",\\",g' \ - -e 's,^,",' \ - -e 's,$$,\\n",' \ - $(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h - $(TCCX) $(TCL_FLAGS) -DTCLSH=2 -DSQLITE_TEST=1 -o \ - sqlite3_analyzer$(EXE) $(TESTSRC) $(TOP)/src/tclsqlite.c \ - libsqlite3.a $(LIBTCL) $(THREADLIB) - -# Rules used to build documentation -# -arch.html: $(TOP)/www/arch.tcl - tclsh $(TOP)/www/arch.tcl >arch.html - -arch.png: $(TOP)/www/arch.png - cp $(TOP)/www/arch.png . - -autoinc.html: $(TOP)/www/autoinc.tcl - tclsh $(TOP)/www/autoinc.tcl >autoinc.html - -c_interface.html: $(TOP)/www/c_interface.tcl - tclsh $(TOP)/www/c_interface.tcl >c_interface.html - -capi3.html: $(TOP)/www/capi3.tcl - tclsh $(TOP)/www/capi3.tcl >capi3.html - -capi3ref.html: $(TOP)/www/capi3ref.tcl - tclsh $(TOP)/www/capi3ref.tcl >capi3ref.html - -changes.html: $(TOP)/www/changes.tcl - tclsh $(TOP)/www/changes.tcl >changes.html - -compile.html: $(TOP)/www/compile.tcl - tclsh $(TOP)/www/compile.tcl >compile.html - -copyright.html: $(TOP)/www/copyright.tcl - tclsh $(TOP)/www/copyright.tcl >copyright.html - -copyright-release.html: $(TOP)/www/copyright-release.html - cp $(TOP)/www/copyright-release.html . - -copyright-release.pdf: $(TOP)/www/copyright-release.pdf - cp $(TOP)/www/copyright-release.pdf . - -common.tcl: $(TOP)/www/common.tcl - cp $(TOP)/www/common.tcl . - -conflict.html: $(TOP)/www/conflict.tcl - tclsh $(TOP)/www/conflict.tcl >conflict.html - -datatypes.html: $(TOP)/www/datatypes.tcl - tclsh $(TOP)/www/datatypes.tcl >datatypes.html - -datatype3.html: $(TOP)/www/datatype3.tcl - tclsh $(TOP)/www/datatype3.tcl >datatype3.html - -docs.html: $(TOP)/www/docs.tcl - tclsh $(TOP)/www/docs.tcl >docs.html - -download.html: $(TOP)/www/download.tcl - mkdir -p doc - tclsh $(TOP)/www/download.tcl >download.html - -faq.html: $(TOP)/www/faq.tcl - tclsh $(TOP)/www/faq.tcl >faq.html - -fileformat.html: $(TOP)/www/fileformat.tcl - tclsh $(TOP)/www/fileformat.tcl >fileformat.html - -formatchng.html: $(TOP)/www/formatchng.tcl - tclsh $(TOP)/www/formatchng.tcl >formatchng.html - -index.html: $(TOP)/www/index.tcl last_change - tclsh $(TOP)/www/index.tcl >index.html - -lang.html: $(TOP)/www/lang.tcl - tclsh $(TOP)/www/lang.tcl doc >lang.html - -pragma.html: $(TOP)/www/pragma.tcl - tclsh $(TOP)/www/pragma.tcl >pragma.html - -lockingv3.html: $(TOP)/www/lockingv3.tcl - tclsh $(TOP)/www/lockingv3.tcl >lockingv3.html - -oldnews.html: $(TOP)/www/oldnews.tcl - tclsh $(TOP)/www/oldnews.tcl >oldnews.html - -omitted.html: $(TOP)/www/omitted.tcl - tclsh $(TOP)/www/omitted.tcl >omitted.html - -opcode.html: $(TOP)/www/opcode.tcl $(TOP)/src/vdbe.c - tclsh $(TOP)/www/opcode.tcl $(TOP)/src/vdbe.c >opcode.html - -mingw.html: $(TOP)/www/mingw.tcl - tclsh $(TOP)/www/mingw.tcl >mingw.html - -nulls.html: $(TOP)/www/nulls.tcl - tclsh $(TOP)/www/nulls.tcl >nulls.html - -quickstart.html: $(TOP)/www/quickstart.tcl - tclsh $(TOP)/www/quickstart.tcl >quickstart.html - -speed.html: $(TOP)/www/speed.tcl - tclsh $(TOP)/www/speed.tcl >speed.html - -sqlite.gif: $(TOP)/art/SQLite.gif - cp $(TOP)/art/SQLite.gif sqlite.gif - -sqlite.html: $(TOP)/www/sqlite.tcl - tclsh $(TOP)/www/sqlite.tcl >sqlite.html - -support.html: $(TOP)/www/support.tcl - tclsh $(TOP)/www/support.tcl >support.html - -tclsqlite.html: $(TOP)/www/tclsqlite.tcl - tclsh $(TOP)/www/tclsqlite.tcl >tclsqlite.html - -vdbe.html: $(TOP)/www/vdbe.tcl - tclsh $(TOP)/www/vdbe.tcl >vdbe.html - -version3.html: $(TOP)/www/version3.tcl - tclsh $(TOP)/www/version3.tcl >version3.html - -whentouse.html: $(TOP)/www/whentouse.tcl - tclsh $(TOP)/www/whentouse.tcl >whentouse.html - - -# Files to be published on the website. -# -DOC = \ - arch.html \ - arch.png \ - autoinc.html \ - c_interface.html \ - capi3.html \ - capi3ref.html \ - changes.html \ - compile.html \ - copyright.html \ - copyright-release.html \ - copyright-release.pdf \ - conflict.html \ - datatypes.html \ - datatype3.html \ - docs.html \ - download.html \ - faq.html \ - fileformat.html \ - formatchng.html \ - index.html \ - lang.html \ - lockingv3.html \ - mingw.html \ - nulls.html \ - oldnews.html \ - omitted.html \ - opcode.html \ - pragma.html \ - quickstart.html \ - speed.html \ - sqlite.gif \ - sqlite.html \ - support.html \ - tclsqlite.html \ - vdbe.html \ - version3.html \ - whentouse.html - -doc: common.tcl $(DOC) - mkdir -p doc - mv $(DOC) doc - -# Standard install and cleanup targets -# -install: sqlite3 libsqlite3.a sqlite3.h - mv sqlite3 /usr/bin - mv libsqlite3.a /usr/lib - mv sqlite3.h /usr/include - -clean: - rm -f *.o sqlite3 libsqlite3.a sqlite3.h opcodes.* - rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h - rm -f $(PUBLISH) - rm -f *.da *.bb *.bbg gmon.out - rm -rf tsrc diff --git a/sqlite/mkopcodec.awk b/sqlite/mkopcodec.awk deleted file mode 100644 index bf6bfbe..0000000 --- a/sqlite/mkopcodec.awk +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/awk -f -# -# This AWK script scans the opcodes.h file (which is itself generated by -# another awk script) and uses the information gleaned to create the -# opcodes.c source file. -# -# Opcodes.c contains strings which are the symbolic names for the various -# opcodes used by the VDBE. These strings are used when disassembling a -# VDBE program during tracing or as a result of the EXPLAIN keyword. -# -BEGIN { - print "/* Automatically generated. Do not edit */" - print "/* See the mkopcodec.awk script for details. */" - printf "#if !defined(SQLITE_OMIT_EXPLAIN)" - printf " || !defined(NDEBUG)" - printf " || defined(VDBE_PROFILE)" - print " || defined(SQLITE_DEBUG)" - print "const char *const sqlite3OpcodeNames[] = { \"?\"," -} -/define OP_/ { - sub("OP_","",$2) - i++ - printf " /* %3d */ \"%s\",\n", $3, $2 -} -END { - print "};" - print "#endif" -} diff --git a/sqlite/mkopcodeh.awk b/sqlite/mkopcodeh.awk deleted file mode 100644 index 641b987..0000000 --- a/sqlite/mkopcodeh.awk +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/awk -f -# -# Generate the file opcodes.h. -# -# This AWK script scans a concatenation of the parse.h output file from the -# parser and the vdbe.c source file in order to generate the opcodes numbers -# for all opcodes. -# -# The lines of the vdbe.c that we are interested in are of the form: -# -# case OP_aaaa: /* same as TK_bbbbb */ -# -# The TK_ comment is optional. If it is present, then the value assigned to -# the OP_ is the same as the TK_ value. If missing, the OP_ value is assigned -# a small integer that is different from every other OP_ value. -# -# We go to the trouble of making some OP_ value the same as TK_ values -# as an optimization. During parsing, things like expression operators -# are coded with TK_ values such as TK_ADD, TK_DIVIDE, and so forth. Later -# during code generation, we need to generate corresponding opcodes like -# OP_Add and OP_Divide. By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide, -# code to translation from one to the other is avoided. This makes the -# code generator run (infinitesimally) faster and more importantly it makes -# the total library smaller. -# - -# Remember the TK_ values from the parse.h file -/^#define TK_/ { - tk[$2] = $3 -} - -# Scan for "case OP_aaaa:" lines in the vdbe.c file -/^case OP_/ { - name = $2 - gsub(/:/,"",name) - gsub("\r","",name) - op[name] = -1 - for(i=3; imax ) max = op[name] - printf "#define %-25s %15d", name, op[name] - if( sameas[op[name]] ) { - printf " /* same as %-12s*/", sameas[op[name]] - } - printf "\n" - - } - seenUnused = 0; - for(i=1; i insert n+1 empty lines -.\" for manpage-specific macros, see man(7) -.SH NAME -sqlite3 \- A command line interface for SQLite verson 3 -.SH SYNOPSIS -.B sqlite -.RI [ options ] " filename " [ SQL ] -.SS SUMMARY -.PP -sqlite is a terminal-based front-end to the SQLite library. It enables -you to type in queries interactively, issue them to SQLite and see the -results. Alternatively, you can specify SQL code on the command-line. In -addition it provides a number of meta-commands. - -.SH DESCRIPTION -This manual page documents briefly the -.B sqlite -command. -This manual page was written for the Debian GNU/Linux distribution -because the original program does not have a manual page. -.SS GETTING STARTED -.PP -To start the sqlite program, just type "sqlite" followed by the name -the file that holds the SQLite database. If the file does not exist, a -new one is created automatically. The sqlite program will then prompt -you to enter SQL. Type in SQL statements (terminated by a semicolon), -press "Enter" and the SQL will be executed. - -For example, to create a new SQLite database named "ex1" with a single -table named "tbl1", you might do this: -.sp -.nf -$ sqlite3 ex1 -SQLite version 3.0.8 -Enter ".help" for instructions -sqlite> create table tbl1(one varchar(10), two smallint); -sqlite> insert into tbl1 values('hello!',10); -sqlite> insert into tbl1 values('goodbye', 20); -sqlite> select * from tbl1; -hello!|10 -goodbye|20 -sqlite> -.sp -.fi - -.SS SQLITE META-COMMANDS -.PP -Most of the time, sqlite just reads lines of input and passes them on -to the SQLite library for execution. But if an input line begins with -a dot ("."), then that line is intercepted and interpreted by the -sqlite program itself. These "dot commands" are typically used to -change the output format of queries, or to execute certain prepackaged -query statements. - -For a listing of the available dot commands, you can enter ".help" at -any time. For example: -.sp -.nf -.cc | -sqlite> .help -.dump ?TABLE? ... Dump the database in an text format -.echo ON|OFF Turn command echo on or off -.exit Exit this program -.explain ON|OFF Turn output mode suitable for EXPLAIN on or off. - "off" will revert to the output mode that was - previously in effect -.header(s) ON|OFF Turn display of headers on or off -.help Show this message -.indices TABLE Show names of all indices on TABLE -.mode MODE Set mode to one of "line(s)", "column(s)", - "insert", "list", or "html" -.mode insert TABLE Generate SQL insert statements for TABLE -.nullvalue STRING Print STRING instead of nothing for NULL data -.output FILENAME Send output to FILENAME -.output stdout Send output to the screen -.prompt MAIN CONTINUE Replace the standard prompts - "sqlite > " and " ...> " - with the strings MAIN and CONTINUE - CONTINUE is optional. -.quit Exit this program -.read FILENAME Execute SQL in FILENAME -.reindex ?TABLE? Rebuild indices -.schema ?TABLE? Show the CREATE statements -.separator STRING Change separator string for "list" mode -.show Show the current values for the following: - .echo - .explain - .mode - .nullvalue - .output - .separator - .width -.tables ?PATTERN? List names of tables matching a pattern -.timeout MS Try opening locked tables for MS milliseconds -.width NUM NUM ... Set column widths for "column" mode -sqlite> -|cc . -.sp -.fi - -.SH OPTIONS -The program has the following options: -.TP -.BI \-init\ file -Read in and process 'file', which contains "dot commands". -You can use this file to initialize display settings. -.TP -.B \-html -Set output mode to HTML. -.TP -.B \-list -Set output mode to 'list'. -.TP -.B \-line -Set output mode to 'line'. -.TP -.B \-column -Set output mode to 'column'. -.TP -.BI \-separator\ separator -Specify which output field separator for 'list' mode to use. -Default is '|'. -.TP -.BI \-nullvalue\ string -When a null is encountered, print 'string'. Default is no string. -.TP -.B \-[no]header -Turn headers on or off. Default is off. -.TP -.B \-echo -Print commands before execution. - - -.SH OUTPUT MODE -The SQLite program has different output modes, which define the way -the output (from queries) is formatted. - -In 'list' mode, which is the default, one record per line is output, -each field separated by the separator specified with the -\fB-separator\fP option or \fB.separator\fP command. - -In 'line' mode, each column is output on its own line, records are -separated by blank lines. - -In HTML mode, an XHTML table is generated. - -In 'column' mode, one record per line is output, aligned neatly in colums. - -.SH INIT FILE -sqlite can be initialized using resource files. These can be combined with -command line arguments to set up sqlite exactly the way you want it. -Initialization proceeds as follows: - -o The defaults of - -.sp -.nf -.cc | -mode = LIST -separator = "|" -main prompt = "sqlite> " -continue prompt = " ...> " -|cc . -.sp -.fi - -are established. - -o If a file .sqliterc can be found in the user's home directory, it is -read and processed. It should only contain "dot commands". If the -file is not found or cannot be read, processing continues without -notification. - -o If a file is specified on the command line with the -init option, it -is processed in the same manner as .sqliterc - -o All other command line options are processed - -o The database is opened and you are now ready to begin. - -.SH SEE ALSO -http://www.hwaci.com/sw/sqlite/ -.br -The sqlite-doc package -.SH AUTHOR -This manual page was originally written by Andreas Rottmann -, for the Debian GNU/Linux system (but may be used -by others). diff --git a/sqlite/src/attach.c b/sqlite/src/attach.c deleted file mode 100644 index 095d2ab..0000000 --- a/sqlite/src/attach.c +++ /dev/null @@ -1,338 +0,0 @@ -/* -** 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.31 2005/01/24 10:25:59 danielk1977 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, *zName; - 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 ) return; -#ifndef SQLITE_OMIT_AUTHORIZATION - if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){ - sqliteFree(zFile); - return; - } -#endif /* SQLITE_OMIT_AUTHORIZATION */ - - zName = sqlite3NameFromToken(pDbname); - if( zName==0 ) return; - for(i=0; inDb; i++){ - char *z = db->aDb[i].zName; - if( z && sqlite3StrICmp(z, zName)==0 ){ - sqlite3ErrorMsg(pParse, "database %z is already in use", zName); - pParse->rc = SQLITE_ERROR; - sqliteFree(zFile); - return; - } - } - - if( db->aDb==db->aDbStatic ){ - aNew = sqliteMalloc( sizeof(db->aDb[0])*3 ); - if( aNew==0 ) return; - memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); - }else{ - aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); - if( aNew==0 ) return; - } - 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; - 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 - sqliteFree(zFile); - 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; - } - } -} - -/* -** 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; - - 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; - for(i=0; inDb; i++){ - pDb = &db->aDb[i]; - if( pDb->pBt==0 || pDb->zName==0 ) continue; - if( strlen(pDb->zName)!=pDbname->n ) continue; - if( sqlite3StrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break; - } - if( i>=db->nDb ){ - sqlite3ErrorMsg(pParse, "no such database: %T", pDbname); - return; - } - if( i<2 ){ - sqlite3ErrorMsg(pParse, "cannot detach database %T", pDbname); - return; - } - 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; inSrc; 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; inExpr; 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/sqlite/src/auth.c b/sqlite/src/auth.c deleted file mode 100644 index aa387cc..0000000 --- a/sqlite/src/auth.c +++ /dev/null @@ -1,224 +0,0 @@ -/* -** 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.21 2005/01/29 08:32:44 danielk1977 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 && iSrcnSrc; iSrc++){ - if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break; - } - if( iSrc>=0 && pTabList && iSrcnSrc ){ - pTab = pTabList->a[iSrc].pTab; - }else if( (pStack = pParse->trigStack)!=0 ){ - /* This must be an attempt to read the NEW or OLD pseudo-tables - ** 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->iColumnnCol ); - zCol = pTab->aCol[pExpr->iColumn].zName; - }else if( pTab->iPKey>=0 ){ - assert( pTab->iPKeynCol ); - zCol = pTab->aCol[pTab->iPKey].zName; - }else{ - zCol = "ROWID"; - } - assert( pExpr->iDbnDb ); - 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/sqlite/src/btree.c b/sqlite/src/btree.c deleted file mode 100644 index 49e817c..0000000 --- a/sqlite/src/btree.c +++ /dev/null @@ -1,5729 +0,0 @@ -/* -** 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.247 2005/02/12 08:59:56 danielk1977 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 - -/* -** This macro rounds values up so that if the value is an address it -** is guaranteed to be an address that is aligned to an 8-byte boundary. -*/ -#define FORCE_ALIGNMENT(X) (((X)+7)&~7) - -/* The following value is the maximum cell size assuming a maximum page -** size give above. -*/ -#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 */ - u16 pageSize; /* Total number of bytes on a page */ - u16 psAligned; /* pageSize rounded up to a multiple of 8 */ - u16 usableSize; /* Number of usable bytes on each page */ - int maxLocal; /* Maximum local payload in non-LEAFDATA tables */ - int minLocal; /* Minimum local payload in non-LEAFDATA tables */ - int maxLeaf; /* Maximum local payload in a LEAFDATA table */ - int minLeaf; /* Minimum local payload in a LEAFDATA table */ -#ifndef SQLITE_OMIT_AUTOVACUUM - u8 autoVacuum; /* True if database supports auto-vacuum */ -#endif -}; -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( iCellhdrOffset+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->psAligned] ); - 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; ileaf*4; i++) used[i] = 1; - nFree = 0; - pc = get2byte(&data[hdr+1]); - while( pc ){ - int size; - assert( pc>0 && pcisInit==0 - || pPage->nFree==nFree+data[hdr+7]+cellLimit-(cellOffset+2*nCell) ); - cellOffset = pPage->cellOffset; - for(i=0; i0 && pcaData) ); - 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; ipBt->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->nFreenOverflow>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( sizecellOffset; - 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]))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->psAligned] ); - if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){ - /* The parent page should never change unless the file is corrupt */ - return SQLITE_CORRUPT; /* bkpt-CORRUPT */ - } - 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->psAligned] == (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->psAligned]; - 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->psAligned]==(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 = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(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 = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(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 ); - assert( sizeof(ptr)==sizeof(char*) ); - assert( sizeof(uptr)==sizeof(ptr) ); - - 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 = 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; - pBt->psAligned = FORCE_ALIGNMENT(pBt->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){ - 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 ){ - pBt->pageSize = pageSize; - pBt->psAligned = FORCE_ALIGNMENT(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; - 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; - } - pBt->pageSize = get2byte(&page1[16]); - pBt->usableSize = pBt->pageSize - page1[20]; - if( pBt->usableSize<500 ){ - goto page1_init_failed; - } - pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize); - pBt->maxEmbedFrac = page1[21]; - pBt->minEmbedFrac = page1[22]; - pBt->minLeafFrac = page1[23]; - } - - /* 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; -} - -/* -** 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->psAligned]; - 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 -** upgrade 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 wrflag is true, then nMaster specifies the maximum length of -** a master journal file name supplied later via sqlite3BtreeSync(). -** This is so that appropriate space can be allocated in the journal file -** when it is created.. -*/ -int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){ - int rc = SQLITE_OK; - - /* 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; - } - if( pBt->readOnly && wrflag ){ - return SQLITE_READONLY; - } - - 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); - } - return rc; -} - -#ifndef SQLITE_OMIT_AUTOVACUUM - -/* -** Set the pointer-map entries for all children of page pPage. Also, if -** pPage contains cells that point to overflow pages, set the pointer -** map entries for the overflow pages as well. -*/ -static int setChildPtrmaps(MemPage *pPage){ - int i; /* Counter variable */ - int nCell; /* Number of cells in page pPage */ - int rc = SQLITE_OK; /* Return code */ - Btree *pBt = pPage->pBt; - int isInitOrig = pPage->isInit; - Pgno pgno = pPage->pgno; - - initPage(pPage, 0); - nCell = pPage->nCell; - - for(i=0; ileaf ){ - Pgno childPgno = get4byte(pCell); - rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno); - if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out; - } - } - - if( !pPage->leaf ){ - Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno); - } - -set_child_ptrmaps_out: - pPage->isInit = isInitOrig; - return rc; -} - -/* -** Somewhere on pPage, which is guarenteed to be a btree page, not an overflow -** page, is a pointer to page iFrom. Modify this pointer so that it points to -** iTo. Parameter eType describes the type of pointer to be modified, as -** follows: -** -** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child -** page of pPage. -** -** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow -** page pointed to by one of the cells on pPage. -** -** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next -** overflow page in the list. -*/ -static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ - if( eType==PTRMAP_OVERFLOW2 ){ - /* The pointer is always the first 4 bytes of the page in this case. */ - if( get4byte(pPage->aData)!=iFrom ){ - return SQLITE_CORRUPT; - } - put4byte(pPage->aData, iTo); - }else{ - int isInitOrig = pPage->isInit; - int i; - int nCell; - - initPage(pPage, 0); - nCell = pPage->nCell; - - for(i=0; iaData[pPage->hdrOffset+8])!=iFrom ){ - return SQLITE_CORRUPT; - } - put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); - } - - pPage->isInit = isInitOrig; - } - return SQLITE_OK; -} - - -/* -** Move the open database page pDbPage to location iFreePage in the -** database. The pDbPage reference remains valid. -*/ -static int relocatePage( - Btree *pBt, /* Btree */ - MemPage *pDbPage, /* Open page to move */ - u8 eType, /* Pointer map 'type' entry for pDbPage */ - Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */ - Pgno iFreePage /* The location to move pDbPage to */ -){ - MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ - Pgno iDbPage = pDbPage->pgno; - Pager *pPager = pBt->pPager; - int rc; - - assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || - eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); - - /* Move page iDbPage from it's current location to page number iFreePage */ - TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", - iDbPage, iFreePage, iPtrPage, eType)); - rc = sqlite3pager_movepage(pPager, pDbPage->aData, iFreePage); - if( rc!=SQLITE_OK ){ - return rc; - } - pDbPage->pgno = iFreePage; - - /* If pDbPage was a btree-page, then it may have child pages and/or cells - ** that point to overflow pages. The pointer map entries for all these - ** pages need to be changed. - ** - ** If pDbPage is an overflow page, then the first 4 bytes may store a - ** pointer to a subsequent overflow page. If this is the case, then - ** the pointer map needs to be updated for the subsequent overflow page. - */ - if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){ - rc = setChildPtrmaps(pDbPage); - if( rc!=SQLITE_OK ){ - return rc; - } - }else{ - Pgno nextOvfl = get4byte(pDbPage->aData); - if( nextOvfl!=0 ){ - rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage); - if( rc!=SQLITE_OK ){ - return rc; - } - } - } - - /* Fix the database pointer on page iPtrPage that pointed at iDbPage so - ** that it points at iFreePage. Also fix the pointer map entry for - ** iPtrPage. - */ - if( eType!=PTRMAP_ROOTPAGE ){ - rc = getPage(pBt, iPtrPage, &pPtrPage); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = sqlite3pager_write(pPtrPage->aData); - if( rc!=SQLITE_OK ){ - releasePage(pPtrPage); - return rc; - } - rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); - releasePage(pPtrPage); - if( rc==SQLITE_OK ){ - rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage); - } - } - return rc; -} - -/* Forward declaration required by autoVacuumCommit(). */ -static int allocatePage(Btree *, MemPage **, Pgno *, Pgno, u8); - -/* -** This routine is called prior to sqlite3pager_commit when a transaction -** is commited for an auto-vacuum database. -*/ -static int autoVacuumCommit(Btree *pBt, Pgno *nTrunc){ - Pager *pPager = pBt->pPager; - Pgno nFreeList; /* Number of pages remaining on the free-list. */ - int nPtrMap; /* Number of pointer-map pages deallocated */ - Pgno origSize; /* Pages in the database file */ - Pgno finSize; /* Pages in the database file after truncation */ - int rc; /* Return code */ - u8 eType; - int pgsz = pBt->pageSize; /* Page size for this database */ - Pgno iDbPage; /* The database page to move */ - MemPage *pDbMemPage = 0; /* "" */ - Pgno iPtrPage; /* The page that contains a pointer to iDbPage */ - Pgno iFreePage; /* The free-list page to move iDbPage to */ - MemPage *pFreeMemPage = 0; /* "" */ - -#ifndef NDEBUG - int nRef = *sqlite3pager_stats(pPager); -#endif - - assert( pBt->autoVacuum ); - if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){ - return SQLITE_CORRUPT; - } - - /* Figure out how many free-pages are in the database. If there are no - ** free pages, then auto-vacuum is a no-op. - */ - nFreeList = get4byte(&pBt->pPage1->aData[36]); - if( nFreeList==0 ){ - *nTrunc = 0; - return SQLITE_OK; - } - - origSize = sqlite3pager_pagecount(pPager); - nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5); - finSize = origSize - nFreeList - nPtrMap; - if( origSize>PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){ - finSize--; - if( PTRMAP_ISPAGE(pBt->usableSize, finSize) ){ - finSize--; - } - } - TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize)); - - /* Variable 'finSize' will be the size of the file in pages after - ** the auto-vacuum has completed (the current file size minus the number - ** of pages on the free list). Loop through the pages that lie beyond - ** this mark, and if they are not already on the free list, move them - ** to a free page earlier in the file (somewhere before finSize). - */ - for( iDbPage=finSize+1; iDbPage<=origSize; iDbPage++ ){ - /* If iDbPage is a pointer map page, or the pending-byte page, skip it. */ - if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){ - continue; - } - - rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage); - if( rc!=SQLITE_OK ) goto autovacuum_out; - assert( eType!=PTRMAP_ROOTPAGE ); - - /* If iDbPage is free, do not swap it. */ - if( eType==PTRMAP_FREEPAGE ){ - continue; - } - rc = getPage(pBt, iDbPage, &pDbMemPage); - if( rc!=SQLITE_OK ) goto autovacuum_out; - - /* Find the next page in the free-list that is not already at the end - ** of the file. A page can be pulled off the free list using the - ** allocatePage() routine. - */ - do{ - if( pFreeMemPage ){ - releasePage(pFreeMemPage); - pFreeMemPage = 0; - } - rc = allocatePage(pBt, &pFreeMemPage, &iFreePage, 0, 0); - if( rc!=SQLITE_OK ){ - releasePage(pDbMemPage); - goto autovacuum_out; - } - assert( iFreePage<=origSize ); - }while( iFreePage>finSize ); - releasePage(pFreeMemPage); - pFreeMemPage = 0; - - rc = relocatePage(pBt, pDbMemPage, eType, iPtrPage, iFreePage); - releasePage(pDbMemPage); - if( rc!=SQLITE_OK ) goto autovacuum_out; - } - - /* The entire free-list has been swapped to the end of the file. So - ** truncate the database file to finSize pages and consider the - ** free-list empty. - */ - rc = sqlite3pager_write(pBt->pPage1->aData); - if( rc!=SQLITE_OK ) goto autovacuum_out; - put4byte(&pBt->pPage1->aData[32], 0); - put4byte(&pBt->pPage1->aData[36], 0); - if( rc!=SQLITE_OK ) goto autovacuum_out; - *nTrunc = finSize; - -autovacuum_out: - assert( nRef==*sqlite3pager_stats(pPager) ); - if( rc!=SQLITE_OK ){ - sqlite3pager_rollback(pPager); - } - return rc; -} -#endif - -/* -** Commit the transaction currently in progress. -** -** 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 - -#if 0 -/* -** Invalidate all cursors -*/ -static void invalidateCursors(Btree *pBt){ - BtCursor *pCur; - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - MemPage *pPage = pCur->pPage; - if( pPage /* && !pPage->isInit */ ){ - pageIntegrity(pPage); - releasePage(pPage); - pCur->pPage = 0; - pCur->isValid = 0; - pCur->status = SQLITE_ABORT; - } - } -} -#endif - -#ifdef SQLITE_TEST -/* -** Print debugging information about all cursors to standard output. -*/ -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, n1readOnly ){ - return SQLITE_READONLY; - } - if( checkReadLocks(pBt, iTable, 0) ){ - return SQLITE_LOCKED; - } - } - if( pBt->pPage1==0 ){ - rc = lockBtree(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; - if( iTable==1 && sqlite3pager_pagecount(pBt->pPager)==0 ){ - rc = SQLITE_EMPTY; - pCur->pPage = 0; - goto create_cursor_exception; - } - pCur->pPage = 0; /* For exit-handler, in case getAndInitPage() fails. */ - 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->idxnCell ); - 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( offsetinfo.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 ){ - 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 ); - assert( pCur->pPage->intKey==0 ); - assert( pCur->idx>=0 && pCur->idxpPage->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->idxpPage->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->idxnCell ); - 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->idxnCell ); - 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( nCellKeynKey ){ - 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->idxpPage->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->idxnCell ); - - 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; isqlite3pager_pagecount(pBt->pPager) ){ - /* Free page off the end of the file */ - return SQLITE_CORRUPT; /* bkpt-CORRUPT */ - } - TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" - ": %d more free pages\n", - *pPgno, closest+1, k, pTrunk->pgno, n-1)); - if( closestaData); - rc = sqlite3pager_write((*ppPage)->aData); - if( rc!=SQLITE_OK ){ - releasePage(*ppPage); - } - } - searchList = 0; - } - } - releasePage(pPrevTrunk); - }while( searchList ); - releasePage(pTrunk); - }else{ - /* There are no pages on the freelist, so create a new page at the - ** end of the file */ - *pPgno = sqlite3pager_pagecount(pBt->pPager) + 1; - -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt->usableSize, *pPgno) ){ - /* If *pPgno refers to a pointer-map page, allocate two new pages - ** at the end of the file instead of one. The first allocated page - ** becomes a new pointer-map page, the second is used by the caller. - */ - TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno)); - assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - (*pPgno)++; - } -#endif - - assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - rc = getPage(pBt, *pPgno, ppPage); - if( rc ) return rc; - rc = sqlite3pager_write((*ppPage)->aData); - if( rc!=SQLITE_OK ){ - releasePage(*ppPage); - } - TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); - } - - assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - return rc; -} - -/* -** 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); - if( rc ) return rc; - sqlite3pager_unref(pOvfl->aData); - } - 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->psAligned]; - 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; inCell; 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 && idxnCell ); - 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; inCell; 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( jaOvfl)/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 ){ - defragmentPage(pPage); - 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; inFree ); - 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; ipBt->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 aCell[] */ - 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[] */ - int mxCellPerPage; /* Maximum number of cells in one page */ - 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; /* 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 - - /* - ** Allocate space for memory structures - */ - mxCellPerPage = MX_CELL(pBt); - apCell = sqliteMallocRaw( - (mxCellPerPage+2)*NB*(sizeof(u8*)+sizeof(int)) - + sizeof(MemPage)*NB - + pBt->psAligned*(5+NB) - + (ISAUTOVACUUM ? (mxCellPerPage+2)*NN*2 : 0) - ); - if( apCell==0 ){ - return SQLITE_NOMEM; - } - szCell = (int*)&apCell[(mxCellPerPage+2)*NB]; - aCopy[0] = (u8*)&szCell[(mxCellPerPage+2)*NB]; - for(i=1; ipsAligned+sizeof(MemPage)]; - } - aSpace = &aCopy[NB-1][pBt->psAligned+sizeof(MemPage)]; -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - aFrom = &aSpace[5*pBt->psAligned]; - } -#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; idxnCell; idx++){ - if( get4byte(findCell(pParent, idx))==pgno ){ - break; - } - } - assert( idxnCell - || 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; inCell ){ - 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++; - } - - /* - ** 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; ipsAligned]; - p->aData = &((u8*)p)[-pBt->psAligned]; - memcpy(p->aData, apOld[i]->aData, pBt->psAligned + sizeof(MemPage)); - p->aData = &((u8*)p)[-pBt->psAligned]; - } - - /* - ** 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; inCell+pOld->nOverflow; - for(j=0; jautoVacuum ){ - int a; - aFrom[nCell] = i; - for(a=0; anOverflow; a++){ - if( pOld->aOvfl[a].pCell==apCell[nCell] ){ - aFrom[nCell] = 0xFF; - break; - } - } - } -#endif - nCell++; - } - if( ipsAligned*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 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; - 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; iaData); - 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( ii ){ - 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; ipgno==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; kpgno!=pNew->pgno ){ - rc = ptrmapPutOvfl(pNew, k-j); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } - } - } -#endif - - j = cntNew[i]; - - /* If the sibling page assembled above was not the right-most sibling, - ** insert a divider cell into the parent page. - */ - if( ileaf ){ - 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->psAligned*5 ); - pTemp = 0; - }else{ - pCell -= 4; - pTemp = &aSpace[iSpace]; - iSpace += sz; - assert( iSpace<=pBt->psAligned*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; iisInit ); - /* assert( pPage->isInit ); // No! pPage might have been added to freelist */ - /* pageIntegrity(pPage); // No! pPage might have been added to freelist */ - rc = balance(pParent, 0); - - /* - ** Cleanup before returning. - */ -balance_cleanup: - sqliteFree(apCell); - for(i=0; ipgno, 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; inCell; 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; inCell; i++){ - rc = ptrmapPutOvfl(pPage, i); - if( rc!=SQLITE_OK ){ - goto end_shallow_balance; - } - } - } -#endif - if( rc!=SQLITE_OK ) goto end_shallow_balance; - releasePage(pChild); - } -end_shallow_balance: - 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 ) return rc; - 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 ) return rc; - for(i=0; inCell; i++){ - rc = ptrmapPutOvfl(pChild, i); - if( rc!=SQLITE_OK ){ - return rc; - } - } - } -#endif - rc = balance_nonroot(pChild); - releasePage(pChild); - return rc; -} - -/* -** 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->idxnCell ); - 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; - assert( !pPage->leafData ); - getTempCursor(pCur, &leafCur); - rc = sqlite3BtreeNext(&leafCur, ¬Used); - if( rc!=SQLITE_OK ){ - if( rc!=SQLITE_NOMEM ){ - rc = SQLITE_CORRUPT; /* bkpt-CORRUPT */ - } - return rc; - } - rc = sqlite3pager_write(leafCur.pPage->aData); - if( rc ) return rc; - 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 ) return SQLITE_NOMEM; - rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0); - if( rc!=SQLITE_OK ) return rc; - put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild); - rc = balance(pPage, 0); - sqliteFree(tempCell); - if( rc ) return rc; - dropCell(leafCur.pPage, leafCur.idx, szNext); - rc = balance(leafCur.pPage, 0); - releaseTempCursor(&leafCur); - }else{ - TRACE(("DELETE: table=%d delete from leaf %d\n", - pCur->pgnoRoot, pPage->pgno)); - dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); - rc = balance(pPage, 0); - } - 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); - assert( eType!=PTRMAP_ROOTPAGE ); - assert( eType!=PTRMAP_FREEPAGE ); - if( rc!=SQLITE_OK ){ - releasePage(pRoot); - return rc; - } - rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove); - releasePage(pRoot); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = getPage(pBt, pgnoRoot, &pRoot); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = sqlite3pager_write(pRoot->aData); - if( rc!=SQLITE_OK ){ - releasePage(pRoot); - return rc; - } - }else{ - pRoot = pPageMove; - } - - /* Update the pointer-map and meta-data with the new root-page number. */ - rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0); - if( rc ){ - releasePage(pRoot); - return rc; - } - rc = sqlite3BtreeUpdateMeta(pBt, 4, pgnoRoot); - if( rc ){ - releasePage(pRoot); - return rc; - } - - }else{ - rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0); - if( rc ) return rc; - } -#endif - assert( sqlite3pager_iswriteable(pRoot->aData) ); - zeroPage(pRoot, flags | PTF_LEAF); - sqlite3pager_unref(pRoot->aData); - *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; - int rc; - unsigned char *pCell; - int i; - - if( pgno>sqlite3pager_pagecount(pBt->pPager) ){ - return SQLITE_CORRUPT; - } - - rc = getAndInitPage(pBt, pgno, &pPage, pParent); - if( rc ) return rc; - rc = sqlite3pager_write(pPage->aData); - if( rc ) return rc; - for(i=0; inCell; i++){ - pCell = findCell(pPage, i); - if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1); - if( rc ) return rc; - } - rc = clearCell(pPage, pCell); - if( rc ) return rc; - } - if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage->pParent, 1); - if( rc ) return rc; - } - if( freePageFlag ){ - rc = freePage(pPage); - }else{ - zeroPage(pPage, pPage->aData[0] | PTF_LEAF); - } - 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 ) 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; ileaf ){ - 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; j0x7f ) 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 && idxpBt->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; iisInit = isInit; - sqlite3pager_unref(data); - fflush(stdout); - return SQLITE_OK; -} -int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ - return btreePageDump(pBt, pgno, recursive, 0); -} -#endif - -#ifdef SQLITE_TEST -/* -** 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.idxnCell ){ - 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 && idxpBt->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; ipBt->autoVacuum ){ - checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext); - } -#endif - checkRef(pCheck, iFreePage, zContext); - } - N -= n; - } - } -#ifndef SQLITE_OMIT_AUTOVACUUM - else{ - /* If this database supports auto-vacuum and iPage is not the last - ** page in this overflow list, check that the pointer-map entry for - ** the following page matches iPage. - */ - if( pCheck->pBt->autoVacuum && N>0 ){ - i = get4byte(pOvfl); - checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext); - } - } -#endif - iPage = get4byte(pOvfl); - sqlite3pager_unref(pOvfl); - } -} -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* -** Do various sanity checks on a single page of a tree. Return -** the tree depth. Root pages return 0. Parents of root pages -** 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; inCell; 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=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 || 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; i1 ){ - 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( lockBtree(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; iautoVacuum && aRoot[i]>1 ){ - checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0); - } -#endif - checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0,0,0,0); - } - - /* Make sure every page in the file is referenced - */ - for(i=1; i<=sCheck.nPage; i++){ -#ifdef SQLITE_OMIT_AUTOVACUUM - if( sCheck.anRef[i]==0 ){ - checkAppendMsg(&sCheck, 0, "Page %d is never used", i); - } -#else - /* If the database supports auto-vacuum, make sure no tables contain - ** references to pointer-map pages. - */ - if( sCheck.anRef[i]==0 && - (PTRMAP_PAGENO(pBt->usableSize, i)!=i || !pBt->autoVacuum) ){ - checkAppendMsg(&sCheck, 0, "Page %d is never used", i); - } - if( sCheck.anRef[i]!=0 && - (PTRMAP_PAGENO(pBt->usableSize, i)==i && pBt->autoVacuum) ){ - checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i); - } -#endif - } - - /* Make sure this analysis did not leave any unref() pages - */ - 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 && nPagepPager, 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; -} diff --git a/sqlite/src/btree.h b/sqlite/src/btree.h deleted file mode 100644 index 7426673..0000000 --- a/sqlite/src/btree.h +++ /dev/null @@ -1,142 +0,0 @@ -/* -** 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.62 2005/02/06 02:45:42 drh 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); - -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/sqlite/src/build.c b/sqlite/src/build.c deleted file mode 100644 index d9328d9..0000000 --- a/sqlite/src/build.c +++ /dev/null @@ -1,3173 +0,0 @@ -/* -** 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.310 2005/02/14 20:48:20 drh Exp $ -*/ -#include "sqliteInt.h" -#include - -/* -** 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; iDbnDb; 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=0; inDb; 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=0; inDb; 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); -} - -/* -** Unlink the given index from its table, then remove -** the index from the index hash table and free its memory -** structures. -*/ -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 && iDbnDb ); - db->flags &= ~SQLITE_Initialized; - for(i=iDb; inDb; 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; inDb; 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; inDb; i++){ - struct Db *pDb = &db->aDb[i]; - if( pDb->pBt==0 ){ - sqliteFree(pDb->zName); - pDb->zName = 0; - continue; - } - if( jaDb[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 ); - for(i=0, pCol=pTable->aCol; inCol; 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; - - /* 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->iDbnDb ); - 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 && iDbnDb ); - 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 really 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( 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 - && 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( isTemp && iDb>1 ){ - /* If creating a temp table, the name may not be qualified */ - sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); - return; - } - if( 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( isTemp ){ - code = SQLITE_CREATE_TEMP_VIEW; - }else{ - code = SQLITE_CREATE_VIEW; - } - }else{ - if( 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; - 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 ){ - sqlite3BeginWriteOperation(pParse, 0, iDb); - - /* Every time a new table is created the file-format - ** and encoding meta-values are set in the database, in - ** case this is the first table created. - */ - 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); - - /* This just creates a place-holder record in the sqlite_master table. - ** The record created does not contain anything yet. It will be replaced - ** by the real entry in code generated at sqlite3EndTable(). - ** - ** The rowid for the new entry is left on the top of the stack. - ** The rowid value is needed by the code that sqlite3EndTable will - ** generate. - */ -#ifndef SQLITE_OMIT_VIEW - if( isView ){ - sqlite3VdbeAddOp(v, OP_Integer, 0, 0); - }else -#endif - { - sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0); - } - sqlite3OpenMasterTable(v, iDb); - sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - } - - /* Normal (non-error) return. */ - return; - - /* If an error occurs, we jump here */ -begin_table_error: - sqliteFree(zName); - return; -} - -/* -** This macro is used to compare two strings in a case-insensitive manner. -** It is slightly faster than calling sqlite3StrICmp() directly, but -** produces larger code. -** -** WARNING: This macro is not compatible with the strcmp() family. It -** returns true if the two strings are equal, otherwise false. -*/ -#define STRICMP(x, y) (\ -sqlite3UpperToLower[*(unsigned char *)(x)]== \ -sqlite3UpperToLower[*(unsigned char *)(y)] \ -&& sqlite3StrICmp((x)+1,(y)+1)==0 ) - -/* -** Add a new column to the table currently being constructed. -** -** 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; inCol; 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 ) 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; iaffinity = 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; inExpr; i++){ - for(iCol=0; iColnCol; iCol++){ - if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){ - break; - } - } - if( iColnCol ) pTab->aCol[iCol].isPrimKey = 1; - } - if( pList->nExpr>1 ) iCol = -1; - } - if( iCol>=0 && iColnCol ){ - 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 " PRIMARY KEY COLLATE ", - ** 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; - } -} - -/* -** 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 ){ - 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; - sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); - } - } - 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; -} - -/* -** 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(Parse *pParse, CollSeq *pColl){ - CollSeq *pColl2; - char *z = pColl->zName; - int n = strlen(z); - sqlite3 *db = pParse->db; - 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; - } - } - if( pParse->nErr==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", n, z); - } - pParse->nErr++; - return SQLITE_ERROR; -} - -/* -** 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 && !pColl->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(pParse->db, pColl->zName, strlen(pColl->zName)); - if( !pColl->xCmp && synthCollSeq(pParse, pColl) ){ - return SQLITE_ERROR; - } - } - return SQLITE_OK; -} - -/* -** 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; inColumn; 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){ - u8 enc = pParse->db->enc; - u8 initbusy = pParse->db->init.busy; - CollSeq *pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, initbusy); - if( nName<0 ) nName = strlen(zName); - if( !initbusy && (!pColl || !pColl->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(pParse->db, zName, nName); - pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, 0); - if( pColl && !pColl->xCmp ){ - /* There may be a version of the collation sequence that requires - ** translation between encodings. Search for it with synthCollSeq(). - */ - if( synthCollSeq(pParse, pColl) ){ - return 0; - } - } - } - - /* If nothing has been found, write the error message into pParse */ - if( !initbusy && (!pColl || !pColl->xCmp) ){ - if( pParse->nErr==0 ){ - 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; inCol; 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, p->iDb==1 ? "CREATE TEMP TABLE " : "CREATE TABLE "); - k = strlen(zStmt); - identPut(zStmt, &k, p->zName); - zStmt[k++] = '('; - for(pCol=p->aCol, i=0; inCol; 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 changes, 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, Token *pEnd, Select *pSelect){ - 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 = Addr(pEnd->z) - Addr(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_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; - - 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, &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 || iTabpIndex; pIdx; pIdx=pIdx->pNext){ - int iIdx = pIdx->tnum; - assert( pIdx->iDb==pTab->iDb ); - if( (iDestroyed==0 || (iIdxiLargest ){ - iLargest = iIdx; - } - } - if( iLargest==0 ) return; - destroyRootPage(pParse, iLargest, pTab->iDb); - iDestroyed = iLargest; - } -#endif -} - -/* -** This routine is called to do the work of a DROP TABLE statement. -** 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 && iDbnDb ); -#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( iDb==1 ){ - code = SQLITE_DROP_TEMP_VIEW; - }else{ - code = SQLITE_DROP_VIEW; - } - }else{ - if( 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; inExpr; 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; inCol; 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; ia[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_IdxPut, iIdx, isUnique); - if( isUnique ){ - sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC); - } - sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1); - sqlite3VdbeChangeP2(v, addr1, sqlite3VdbeCurrentAddr(v)); - sqlite3VdbeAddOp(v, OP_Close, iTab, 0); - sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); -} - -/* -** Create a new index for an SQL table. 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 */ - int isTemp; /* True for a temporary index */ - 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; - - /* 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; - } - - 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 - isTemp = pTab->iDb==1; - - /* - ** 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[pTab->iDb].zName; - if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ - goto exit_create_index; - } - i = SQLITE_CREATE_INDEX; - if( isTemp ) 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( pIndex==0 ) 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; inExpr; i++){ - for(j=0; jnCol; 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; knColumn; 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", - Addr(pEnd->z) - Addr(pName->z) + 1, - pName->z); - }else{ - /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ - /* zStmt = sqlite3MPrintf(""); */ - zStmt = 0; - } - - /* 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 ) return; - assert( pName->nSrc==1 ); - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) return; - 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( 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; inSrc; 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; inId; i++){ - sqliteFree(pList->a[i].zName); - } - sqliteFree(pList->a); - sqliteFree(pList); -} - -/* -** Return the index in pList of the identifier named zId. Return -1 -** if not found. -*/ -int sqlite3IdListIndex(IdList *pList, const char *zName){ - int i; - if( pList==0 ) return -1; - for(i=0; inId; i++){ - if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; - } - return -1; -} - -/* -** Delete an entire SrcList including all its substructure. -*/ -void sqlite3SrcListDelete(SrcList *pList){ - int i; - struct SrcList_item *pItem; - if( pList==0 ) return; - for(pItem=pList->a, i=0; inSrc; i++, pItem++){ - sqliteFree(pItem->zDatabase); - sqliteFree(pItem->zName); - sqliteFree(pItem->zAlias); - if( pItem->pTab && pItem->pTab->isTransient ){ - 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; inDb; 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( iDbnDb ); - assert( db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDb<32 ); - mask = 1<cookieMask & mask)==0 ){ - pParse->cookieMask |= mask; - pParse->cookieValue[iDb] = db->aDb[iDb].schema_cookie; - if( 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<nested==0 ){ - sqlite3VdbeAddOp(v, OP_Statement, iDb, 0); - } - if( iDb!=1 && pParse->db->aDb[1].pBt!=0 ){ - sqlite3BeginWriteOperation(pParse, setStatement, 1); - } -} - -#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 - -/* -** Check to see if pIndex uses the collating sequence pColl. Return -** true if it does and false if it does not. -*/ -#ifndef SQLITE_OMIT_REINDEX -static int collationMatch(CollSeq *pColl, Index *pIndex){ - int n = pIndex->keyInfo.nField; - CollSeq **pp = pIndex->keyInfo.aColl; - while( n-- ){ - if( *pp==pColl ) return 1; - pp++; - } - return 0; -} -#endif - -/* -** Recompute all indices of pTab that use the collating sequence pColl. -** If pColl==0 then recompute all indices of pTab. -*/ -#ifndef SQLITE_OMIT_REINDEX -void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){ - Index *pIndex; /* An index associated with pTab */ - - for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ - if( pColl==0 || collationMatch(pColl,pIndex) ){ - sqlite3BeginWriteOperation(pParse, 0, pTab->iDb); - sqlite3RefillIndex(pParse, pIndex, -1); - } - } -} -#endif - -/* -** Recompute all indices of all tables in all databases where the -** indices use the collating sequence pColl. If pColl==0 then recompute -** all indices everywhere. -*/ -#ifndef SQLITE_OMIT_REINDEX -void reindexDatabases(Parse *pParse, CollSeq *pColl){ - Db *pDb; /* A single database */ - int iDb; /* The database index number */ - sqlite3 *db = pParse->db; /* The database connection */ - HashElem *k; /* For looping over tables in pDb */ - Table *pTab; /* A table in the database */ - - for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ - if( pDb==0 ) continue; - for(k=sqliteHashFirst(&pDb->tblHash); k; k=sqliteHashNext(k)){ - pTab = (Table*)sqliteHashData(k); - reindexTable(pParse, pTab, pColl); - } - } -} -#endif - -/* -** Generate code for the REINDEX command. -** -** REINDEX -- 1 -** REINDEX -- 2 -** REINDEX ?.? -- 3 -** REINDEX ?.? -- 4 -** -** Form 1 causes all indices in all attached databases to be rebuilt. -** Form 2 rebuilds all indices in all databases that use the named -** collating function. Forms 3 and 4 rebuild the named index or all -** indices associated with the named table. -*/ -#ifndef SQLITE_OMIT_REINDEX -void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ - CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */ - char *z; /* Name of a table or index */ - const char *zDb; /* Name of the database */ - Table *pTab; /* A table in the database */ - Index *pIndex; /* An index associated with pTab */ - int iDb; /* The database index number */ - sqlite3 *db = pParse->db; /* The database connection */ - Token *pObjName; /* Name of the table or index to be reindexed */ - - /* Read the database schema. If an error occurs, leave an error message - ** and code in pParse and return NULL. */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - return; - } - - if( pName1==0 || pName1->z==0 ){ - reindexDatabases(pParse, 0); - return; - }else if( pName2==0 || pName2->z==0 ){ - pColl = sqlite3FindCollSeq(db, db->enc, pName1->z, pName1->n, 0); - if( pColl ){ - reindexDatabases(pParse, pColl); - return; - } - } - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); - if( iDb<0 ) return; - z = sqlite3NameFromToken(pObjName); - zDb = db->aDb[iDb].zName; - pTab = sqlite3FindTable(db, z, zDb); - if( pTab ){ - reindexTable(pParse, pTab, 0); - sqliteFree(z); - return; - } - pIndex = sqlite3FindIndex(db, z, zDb); - sqliteFree(z); - if( pIndex ){ - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3RefillIndex(pParse, pIndex, -1); - return; - } - sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); -} -#endif - -#ifndef SQLITE_OMIT_ALTERTABLE -/* -** 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 */ - char *zWhere = 0; /* Where clause of schema elements to reparse */ - sqlite3 *db = pParse->db; /* Database connection */ - Vdbe *v; -#ifndef SQLITE_OMIT_TRIGGER - char *zTempTrig = 0; /* Where clause to locate temp triggers */ -#endif - - assert( pSrc->nSrc==1 ); - - pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); - if( !pTab ) goto exit_alter_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_alter_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_alter_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_alter_table; - } - if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - goto exit_alter_table; - } - -#ifndef SQLITE_OMIT_AUTHORIZATION - /* Invoke the authorization callback. */ - if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ - goto exit_alter_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_alter_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_alter_table(sql, %Q), " -#else - "sql = CASE " - "WHEN type = 'trigger' THEN sqlite_alter_trigger(sql, %Q)" - "ELSE sqlite_alter_table(sql, %Q) END, " -#endif - "tbl_name = %Q, " - "name = CASE " - "WHEN type='table' THEN %Q " - "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " - "'sqlite_autoindex_' || %Q || substr(name, %d+18,10) " - "ELSE name END " - "WHERE tbl_name=%Q AND " - "(type='table' OR type='index' OR type='trigger');", - zDb, SCHEMA_TABLE(iDb), zName, zName, zName, -#ifndef SQLITE_OMIT_TRIGGER -zName, -#endif - zName, strlen(pTab->zName), pTab->zName - ); - -#ifndef SQLITE_OMIT_AUTOINCREMENT - /* If the sqlite_sequence table exists in this database, then update - ** it with the new table name. - */ - if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ - sqlite3NestedParse(pParse, - "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q", - zDb, zName, pTab->zName); - } -#endif - -#ifndef SQLITE_OMIT_TRIGGER - /* If there are TEMP triggers on this table, modify the sqlite_temp_master - ** table. Don't do this if the table being ALTERed is itself located in - ** the temp database. - */ - if( iDb!=1 ){ - Trigger *pTrig; - char *tmp = 0; - for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){ - if( pTrig->iDb==1 ){ - if( !zTempTrig ){ - zTempTrig = - sqlite3MPrintf("type = 'trigger' AND (name=%Q", pTrig->name); - }else{ - tmp = zTempTrig; - zTempTrig = sqlite3MPrintf("%s OR name=%Q", zTempTrig, pTrig->name); - sqliteFree(tmp); - } - } - } - if( zTempTrig ){ - tmp = zTempTrig; - zTempTrig = sqlite3MPrintf("%s)", zTempTrig); - sqliteFree(tmp); - sqlite3NestedParse(pParse, - "UPDATE sqlite_temp_master SET " - "sql = sqlite_alter_trigger(sql, %Q), " - "tbl_name = %Q " - "WHERE %s;", zName, zName, zTempTrig); - } - } -#endif - - /* Drop the elements of the in-memory schema that refered to the table - ** renamed and load the new versions from the database. - */ - if( pParse->nErr==0 ){ -#ifndef SQLITE_OMIT_TRIGGER - Trigger *pTrig; - for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){ - assert( pTrig->iDb==iDb || pTrig->iDb==1 ); - sqlite3VdbeOp3(v, OP_DropTrigger, pTrig->iDb, 0, pTrig->name, 0); - } -#endif - sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); - zWhere = sqlite3MPrintf("tbl_name=%Q", zName); - sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC); -#ifndef SQLITE_OMIT_TRIGGER - if( zTempTrig ){ - sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zTempTrig, P3_DYNAMIC); - } - }else{ - sqliteFree(zTempTrig); -#endif - } - -exit_alter_table: - sqlite3SrcListDelete(pSrc); - sqliteFree(zName); -} -#endif diff --git a/sqlite/src/date.c b/sqlite/src/date.c deleted file mode 100644 index d472e58..0000000 --- a/sqlite/src/date.c +++ /dev/null @@ -1,1000 +0,0 @@ -/* -** 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.43 2005/01/15 01:52:32 drh 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 -#include -#include -#include - -#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( valmax || (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) ){ 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; nrJD += 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; izErrMsg 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; inSrc; i++, pItem++){ - pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase); - pItem->pTab = pTab; - } - 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 ){ - pTabList = 0; - 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->iDbnDb ); - 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, 0); - if( pWInfo==0 ) goto delete_from_cleanup; - - /* Remember the rowid of every item to be deleted. - */ - sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); - sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0); - if( db->flags & SQLITE_CountRows ){ - sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); - } - - /* 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); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - if( !isView ){ - sqlite3OpenTableForReading(v, iCur, pTab); - } - sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); - sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); - sqlite3VdbeAddOp(v, OP_RowData, iCur, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, 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_Recno, iCur, 0); - for(j=0; jnColumn; j++){ - int idx = pIdx->aiColumn[j]; - if( idx==pTab->iPKey ){ - sqlite3VdbeAddOp(v, OP_Dup, j, 0); - }else{ - sqlite3VdbeAddOp(v, OP_Column, iCur, idx); - } - } - sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24)); - sqlite3IndexAffinityStr(v, pIdx); -} diff --git a/sqlite/src/experimental.c b/sqlite/src/experimental.c deleted file mode 100644 index 7de6f7c..0000000 --- a/sqlite/src/experimental.c +++ /dev/null @@ -1,38 +0,0 @@ - -/* -** 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: experimental.c,v 1.2 2005/01/20 01:17:44 danielk1977 Exp $ -*/ -#include "sqliteInt.h" - -/* -** Set all the parameters in the compiled SQL statement to NULL. -*/ -int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ - int i; - int rc = SQLITE_OK; - for(i=1; rc==SQLITE_OK && i<=sqlite3_bind_parameter_count(pStmt); i++){ - rc = sqlite3_bind_null(pStmt, i); - } - return rc; -} - -/* -** Sleep for a little while. Return the amount of time slept. -*/ -int sqlite3_sleep(int ms){ - return sqlite3OsSleep(ms); -} - diff --git a/sqlite/src/expr.c b/sqlite/src/expr.c deleted file mode 100644 index f27bed5..0000000 --- a/sqlite/src/expr.c +++ /dev/null @@ -1,2173 +0,0 @@ -/* -** 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.194 2005/02/12 08:59:57 danielk1977 Exp $ -*/ -#include "sqliteInt.h" -#include - -/* -** 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))<<8)+(jumpIfNull?1: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, we leak memory from pLeft and 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 + Addr(pRight->z) - Addr(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); // Leak pList 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; inVarExpr; 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); - 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; inExpr; 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; inSrc; i++){ - struct SrcList_item *pNewItem = &pNew->a[i]; - struct SrcList_item *pOldItem = &p->a[i]; - pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase); - pNewItem->zName = sqliteStrDup(pOldItem->zName); - pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias); - pNewItem->jointype = pOldItem->jointype; - pNewItem->iCursor = pOldItem->iCursor; - pNewItem->pTab = pOldItem->pTab; - if( pNewItem->pTab ){ - pNewItem->pTab->isTransient = 0; - } - pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect); - pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn); - pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing); - pNewItem->colUsed = pOldItem->colUsed; - } - return pNew; -} -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 ) return 0; - for(i=0; inId; 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->pFetch = 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 ){ - /* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */ - return 0; - } - assert( pList->nAlloc==0 ); - } - if( pList->nAlloc<=pList->nExpr ){ - pList->nAlloc = pList->nAlloc*2 + 4; - pList->a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0])); - if( pList->a==0 ){ - /* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */ - pList->nExpr = pList->nAlloc = 0; - return pList; - } - } - assert( pList->a!=0 ); - if( pExpr || pName ){ - struct ExprList_item *pItem = &pList->a[pList->nExpr++]; - memset(pItem, 0, sizeof(*pItem)); - pItem->pExpr = pExpr; - pItem->zName = sqlite3NameFromToken(pName); - } - return pList; -} - -/* -** 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; inExpr; 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 ){ - return 1; /* Leak memory (zDb and zTab) if malloc fails */ - } - - pExpr->iTable = -1; - while( pNC && cnt==0 ){ - SrcList *pSrcList = pNC->pSrcList; - ExprList *pEList = pNC->pEList; - - pNC->nRef++; - /* assert( zTab==0 || pEList==0 ); */ - if( pSrcList ){ - for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ - Table *pTab = pItem->pTab; - Column *pCol; - - if( pTab==0 ) continue; - assert( pTab->nCol>0 ); - if( zTab ){ - if( pItem->zAlias ){ - char *zTabName = pItem->zAlias; - if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; - }else{ - char *zTabName = pTab->zName; - if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue; - if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){ - continue; - } - } - } - if( 0==(cntTab++) ){ - pExpr->iTable = pItem->iCursor; - pExpr->iDb = pTab->iDb; - pMatch = pItem; - } - for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ - if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - cnt++; - pExpr->iTable = pItem->iCursor; - pMatch = pItem; - pExpr->iDb = pTab->iDb; - /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ - pExpr->iColumn = j==pTab->iPKey ? -1 : j; - pExpr->affinity = pTab->aCol[j].affinity; - pExpr->pColl = pTab->aCol[j].pColl; - break; - } - } - } - } - -#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; - 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; jnExpr; j++){ - char *zAs = pEList->a[j].zName; - if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ - assert( pExpr->pLeft==0 && pExpr->pRight==0 ); - pExpr->op = TK_AS; - pExpr->iColumn = j; - pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr); - sqliteFree(zCol); - assert( zTab==0 && zDb==0 ); - return 0; - } - } - } - - /* Advance to the next name context. The loop will exit when either - ** we have a match (cnt>0) or when we run out of name contexts. - */ - if( cnt==0 ){ - pNC = pNC->pNext; - } - } - - /* - ** 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. - */ - 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<pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(pExpr->pRight); - pExpr->pRight = 0; - pExpr->op = TK_COLUMN; - if( cnt==1 ){ - assert( pNC!=0 ); - sqlite3AuthRead(pParse, pExpr, pNC->pSrcList); - } - return cnt!=1; -} - -/* -** pExpr is a node that defines a function of some kind. It might -** be a syntactic function like "count(x)" or it might be a function -** that implements an operator, like "a LIKE b". -** -** This routine makes *pzName point to the name of the function and -** *pnName hold the number of characters in the function name. -*/ -static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){ - switch( pExpr->op ){ - case TK_FUNCTION: { - *pzName = pExpr->token.z; - *pnName = pExpr->token.n; - break; - } - case TK_LIKE: { - *pzName = "like"; - *pnName = 4; - break; - } - case TK_GLOB: { - *pzName = "glob"; - *pnName = 4; - break; - } - case TK_CTIME: { - *pzName = "current_time"; - *pnName = 12; - break; - } - case TK_CDATE: { - *pzName = "current_date"; - *pnName = 12; - break; - } - case TK_CTIMESTAMP: { - *pzName = "current_timestamp"; - *pnName = 17; - break; - } - } -} - -/* -** This routine is designed as an xFunc for walkExprTree(). -** -** 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; inSrc; i++){ - assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab); - } - } -#endif - switch( pExpr->op ){ - /* Double-quoted strings (ex: "abc") are used as identifiers if - ** possible. Otherwise they remain as strings. Single-quoted - ** 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_CTIME: - case TK_CTIMESTAMP: - case TK_CDATE: - case TK_GLOB: - case TK_LIKE: - case TK_FUNCTION: { - ExprList *pList = pExpr->pList; /* The argument list */ - int n = pList ? pList->nExpr : 0; /* Number of arguments */ - int no_such_func = 0; /* True if no such function exists */ - int wrong_num_args = 0; /* True if wrong number of arguments */ - int is_agg = 0; /* True if is an aggregate function */ - int i; - int nId; /* Number of characters in function name */ - const char *zId; /* The function name. */ - FuncDef *pDef; /* Information about the function */ - int enc = pParse->db->enc; /* The database encoding */ - - getFunctionName(pExpr, &zId, &nId); - pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); - if( pDef==0 ){ - pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); - if( pDef==0 ){ - no_such_func = 1; - }else{ - wrong_num_args = 1; - } - }else{ - is_agg = pDef->xFunc==0; - } - if( is_agg && !pNC->allowAgg ){ - sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); - pNC->nErr++; - is_agg = 0; - }else if( no_such_func ){ - sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); - pNC->nErr++; - }else if( wrong_num_args ){ - sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", - nId, zId); - pNC->nErr++; - } - if( is_agg ){ - pExpr->op = TK_AGG_FUNCTION; - pNC->hasAgg = 1; - } - if( is_agg ) pNC->allowAgg = 0; - for(i=0; pNC->nErr==0 && ia[i].pExpr, nameResolverStep, pNC); - } - if( is_agg ) pNC->allowAgg = 1; - /* FIX ME: Compute pExpr->affinity based on the expected return - ** type of the function - */ - return is_agg; - } -#ifndef SQLITE_OMIT_SUBQUERY - case TK_SELECT: - case TK_EXISTS: -#endif - case TK_IN: { - if( pExpr->pSelect ){ - int nRef = pNC->nRef; - sqlite3SelectResolve(pParse, pExpr->pSelect, pNC); - assert( pNC->nRef>=nRef ); - if( nRef!=pNC->nRef ){ - ExprSetProperty(pExpr, EP_VarSelect); - } - } - } - } - 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()' - ** 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 . - ** - ** 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 is a column, then use - ** that columns affinity when building index keys. If 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 . */ - for(i=0; ipList->nExpr; i++){ - Expr *pE2 = pExpr->pList->a[i].pExpr; - - /* Check that the expression is constant and valid. */ - if( !sqlite3ExprIsConstant(pE2) ){ - sqlite3ErrorMsg(pParse, - "right-hand side of IN operator must be constant"); - return; - } - - /* Evaluate the expression and insert it into the temp table */ - sqlite3ExprCode(pParse, pE2); - sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutStrKey, 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_String8, 0, 0); /* Empty expression evals to NULL */ - 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); -#ifndef NDEBUG - if( pExpr->span.z && pExpr->span.n>0 && pExpr->span.n<100 ){ - VdbeComment((v, "# %T", &pExpr->span)); - } -#endif - }else{ - sqlite3VdbeAddOp(v, OP_Recno, 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; - } -#ifndef SQLITE_OMIT_BLOB_LITERAL - case TK_BLOB: { - assert( TK_BLOB==OP_HexBlob ); - sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z+1, pExpr->token.n-1); - sqlite3VdbeDequoteP3(v, -1); - break; - } -#endif - case TK_NULL: { - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - break; - } - 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_CDATE: - case TK_CTIME: - case TK_CTIMESTAMP: - case TK_GLOB: - case TK_LIKE: - 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; - getFunctionName(pExpr, &zId, &nId); - pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); - assert( pDef!=0 ); - nExpr = sqlite3ExprCodeExprList(pParse, pList); - for(i=0; ia[i].pExpr) ){ - p2 |= (1<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 from " 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_String8, 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; ipLeft ){ - 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_String8, 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; ipExpr); - } - 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 - ** 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 - ** 3 IF (x > z) GOTO - */ - 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; ipList->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 && inSrc; i++){ - if( pExpr->iTable==pSrcList->a[i].iCursor ){ - aAgg = pParse->aAgg; - for(i=0; inAgg; i++){ - if( aAgg[i].isAgg ) continue; - if( aAgg[i].pExpr->iTable==pExpr->iTable - && aAgg[i].pExpr->iColumn==pExpr->iColumn ){ - break; - } - } - if( i>=pParse->nAgg ){ - i = appendAggInfo(pParse); - if( i<0 ) return 1; - pParse->aAgg[i].isAgg = 0; - pParse->aAgg[i].pExpr = pExpr; - } - pExpr->iAgg = i; - pExpr->iAggCtx = pNC->nDepth; - return 1; - } - } - return 1; - } - case TK_AGG_FUNCTION: { - if( pNC->nDepth==0 ){ - aAgg = pParse->aAgg; - for(i=0; inAgg; i++){ - if( !aAgg[i].isAgg ) continue; - if( sqlite3ExprCompare(aAgg[i].pExpr, pExpr) ){ - break; - } - } - if( i>=pParse->nAgg ){ - u8 enc = pParse->db->enc; - i = appendAggInfo(pParse); - if( i<0 ) return 1; - pParse->aAgg[i].isAgg = 1; - pParse->aAgg[i].pExpr = pExpr; - pParse->aAgg[i].pFunc = sqlite3FindFunction(pParse->db, - pExpr->token.z, pExpr->token.n, - pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0); - } - pExpr->iAgg = i; - 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; -} - -/* -** 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/sqlite/src/func.c b/sqlite/src/func.c deleted file mode 100644 index f5e633c..0000000 --- a/sqlite/src/func.c +++ /dev/null @@ -1,1195 +0,0 @@ -/* -** 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.94 2005/02/09 01:40:25 danielk1977 Exp $ -*/ -#include "sqliteInt.h" -#include -#include -#include -#include -#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=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; i30 ) 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; imatchOne; - 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); -} - -#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_alter_table('CREATE TABLE abc(a, b, c)', 'def') -** -> 'CREATE TABLE def(a, b, c)' -** -** sqlite_alter_table('CREATE INDEX i ON abc(a)', 'def') -** -> 'CREATE INDEX i ON def(a, b, c)' -*/ -static void altertableFunc( - 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); - } -} -#endif - -#ifndef SQLITE_OMIT_ALTERTABLE -#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 altertableFunc() above, except for CREATE -** TRIGGER, not CREATE INDEX and CREATE TABLE. -*/ -static void altertriggerFunc( - 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 */ -#endif /* !SQLITE_OMIT_ALTERTABLE */ - -/* -** 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>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=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( nenc); - 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; isum += 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 */ -}; - -#if 0 /* Omit because math library is required */ -/* -** Routines used to compute the standard deviation as an aggregate. -*/ -static void stdDevStep(sqlite3_context *context, int argc, const char **argv){ - StdDevCtx *p; - double x; - if( argc<1 ) return; - p = sqlite3_aggregate_context(context, sizeof(*p)); - if( p && argv[0] ){ - x = sqlite3AtoF(argv[0], 0); - p->sum += x; - p->sum2 += x*x; - p->cnt++; - } -} -static void stdDevFinalize(sqlite3_context *context){ - double rN = sqlite3_aggregate_count(context); - StdDevCtx *p = sqlite3_aggregate_context(context, sizeof(*p)); - if( p && p->cnt>1 ){ - double rCnt = cnt; - sqlite3_set_result_double(context, - sqrt((p->sum2 - p->sum*p->sum/rCnt)/(rCnt-1.0))); - } -} -#endif - -/* -** The following structure keeps track of state information for the -** count() aggregate function. -*/ -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 }, -#ifndef SQLITE_OMIT_ALTERTABLE - { "sqlite_alter_table", 2, 0, SQLITE_UTF8, 0, altertableFunc}, -#ifndef SQLITE_OMIT_TRIGGER - { "sqlite_alter_trigger", 2, 0, SQLITE_UTF8, 0, altertriggerFunc}, -#endif -#endif -#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 }, -#if 0 - { "stddev", 1, 0, stdDevStep, stdDevFinalize }, -#endif - }; - int i; - - for(i=0; ineedCollSeq = 1; - } - } - } - for(i=0; ineedCollSeq = 1; - } - } - } - sqlite3RegisterDateTimeFunctions(db); -} diff --git a/sqlite/src/hash.c b/sqlite/src/hash.c deleted file mode 100644 index b7b2138..0000000 --- a/sqlite/src/hash.c +++ /dev/null @@ -1,387 +0,0 @@ -/* -** 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.16 2005/01/31 12:56:44 danielk1977 Exp $ -*/ -#include "sqliteInt.h" -#include - -/* 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 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/sqlite/src/insert.c b/sqlite/src/insert.c deleted file mode 100644 index 7f25448..0000000 --- a/sqlite/src/insert.c +++ /dev/null @@ -1,1111 +0,0 @@ -/* -** 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.136 2005/02/08 08:42:28 danielk1977 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; nnColumn; 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; inCol; 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 SELECT ..." can run without using temporary -** table for the results of the SELECT. -** -** No checking is done for sub-selects that are part of expressions. -*/ -static int selectReadsTable(Select *p, int iDb, int iTab){ - int i; - struct SrcList_item *pItem; - if( p->pSrc==0 ) return 0; - for(i=0, pItem=p->pSrc->a; ipSrc->nSrc; i++, pItem++){ - if( pItem->pSelect ){ - if( selectReadsTable(p, iDb, iTab) ) return 1; - }else{ - if( pItem->pTab->iDb==iDb && pItem->pTab->tnum==iTab ) return 1; - } - } - return 0; -} - -/* -** This routine is call to handle SQL of the following forms: -** -** 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 and its indices -** puts VALUES clause expressions onto the stack -** write the resulting record into
-** cleanup -** -** If the statement is of the form -** -** INSERT INTO
SELECT ... -** -** And the SELECT clause does not read from
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
and its indices -** goto A -** C: insert the select result into
-** 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
and its indices -** loop over the intermediate table -** transfer values form intermediate table into
-** 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->iDbnDb ); - 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_Recno, iCur, 0); - sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1); - sqlite3VdbeAddOp(v, OP_Column, iCur, 1); - sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1); - sqlite3VdbeAddOp(v, OP_Goto, 0, base+13); - sqlite3VdbeAddOp(v, OP_Next, iCur, base+4); - sqlite3VdbeAddOp(v, OP_Close, iCur, 0); - } -#endif /* SQLITE_OMIT_AUTOINCREMENT */ - - /* Figure out how many columns of data are supplied. If the data - ** is coming from a SELECT statement, then this step also generates - ** all the code to implement the SELECT statement and invoke a subroutine - ** 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_NewRecno, srcTab, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, 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; ia[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; inId; i++){ - pColumn->a[i].idx = -1; - } - for(i=0; inId; i++){ - for(j=0; jnCol; 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; inCol; i++){ - if( pColumn==0 ){ - j = i; - }else{ - for(j=0; jnId; 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_PutIntKey, 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 NewRecno - ** 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_NewRecno - ** to generate a unique primary key value. - */ - sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem); - sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); - }else{ - sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem); - } -#ifndef SQLITE_OMIT_AUTOINCREMENT - if( pTab->autoInc ){ - sqlite3VdbeAddOp(v, OP_MemMax, counterMem, 0); - } -#endif /* SQLITE_OMIT_AUTOINCREMENT */ - - /* Push onto the stack, data for all columns of the new entry, beginning - ** with the first column. - */ - for(i=0; inCol; 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_String8, 0, 0); - continue; - } - if( pColumn==0 ){ - j = i; - }else{ - for(j=0; jnId; 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_NewRecno, iCur, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); - sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0); - sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, iCur, 0); - sqlite3VdbeAddOp(v, OP_Close, iCur, 0); - } -#endif - - /* - ** Return the number of rows inserted. 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); - if( pList ) sqlite3ExprListDelete(pList); - if( pSelect ) 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 recno 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 recno 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 recno shown as entry (1) above is omitted unless both isUpdate -** and recnoChng are 1. isUpdate is true for UPDATEs and false for -** INSERTs and recnoChng 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 recnoChng, /* 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 hasTwoRecnos = (isUpdate && recnoChng); - - 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; iiPKey ){ - 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+hasTwoRecnos, 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( recnoChng ){ - 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+hasTwoRecnos, 1); - sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); - } - seenReplace = 1; - break; - } - case OE_Ignore: { - assert( seenReplace==0 ); - sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 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; inColumn; 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+hasTwoRecnos, 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; jnColumn && n1aCol[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+hasTwoRecnos, 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+hasTwoRecnos, 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 recno 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 recnoChng, /* 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_IdxPut, 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_PutIntKey, newIdx, 0); - } -#endif - if( pParse->nested ){ - pik_flags = 0; - }else{ - pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID)); - } - sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags); - - if( isUpdate && recnoChng ){ - 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/sqlite/src/main.c b/sqlite/src/main.c deleted file mode 100644 index d36777d..0000000 --- a/sqlite/src/main.c +++ /dev/null @@ -1,1389 +0,0 @@ -/* -** 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.280 2005/02/06 02:45:42 drh Exp $ -*/ -#include "sqliteInt.h" -#include "os.h" -#include - -/* -** The following constant value is used by the SQLITE_BIGENDIAN and -** SQLITE_LITTLEENDIAN macros. -*/ -const int sqlite3one = 1; - -/* -** 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 && iDbnDb ); - 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; - - /* - ** 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" - ")" - ; - 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" - ")" - ; - - assert( iDb>=0 && iDbnDb ); - - /* zMasterSchema and zInitScript are set to point at the master schema - ** and initialisation script appropriate for the database being - ** initialised. zMasterName is the name of the master table. - */ - if( iDb==1 ){ - zMasterSchema = temp_master_schema; - zMasterName = TEMP_MASTER_NAME; - }else{ - zMasterSchema = master_schema; - zMasterName = MASTER_NAME; - } - - /* Construct the schema tables. */ - 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( 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 && iaDb[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; - } - } - - /* - ** file_format==1 Version 3.0.0. - */ - if( meta[1]>1 ){ - 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 && inDb; 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. - */ - if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ - rc = sqlite3InitOne(db, 1, pzErrMsg); - if( rc ){ - sqlite3ResetInternalSchema(db, 1); - } - } - - 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; -} - -/* -** 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 = nKey1lastRowid; -} - -/* -** 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; - } - - /* 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; jnDb; 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); - } - - db->magic = SQLITE_MAGIC_ERROR; - sqliteFree(db); - return SQLITE_OK; -} - -/* -** Rollback all database files. -*/ -void sqlite3RollbackAll(sqlite3 *db){ - int i; - for(i=0; inDb; 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 *Timeout, /* Maximum amount of time to wait */ - int count /* Number of times table has been busy */ -){ -#if SQLITE_MIN_SLEEP_MS==1 - static const char delays[] = - { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 50, 100}; - static const short int totals[] = - { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228, 287}; -# define NDELAY (sizeof(delays)/sizeof(delays[0])) - ptr timeout = (ptr)Timeout; - ptr delay, prior; - - if( count <= NDELAY ){ - delay = delays[count-1]; - prior = totals[count-1]; - }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 = (int)Timeout; - 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 ){ - sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)(ptr)ms); - }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; -} - -/* -** 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 && iDbnDb; 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 */ - -/* -** 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. The fourth argument, "def_enc" is one of the TEXT_* -** macros from sqliteInt.h. If we end up creating a new database file -** (not opening an existing one), the text encoding of the database -** will be set to this value. -*/ -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; inDb; 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; - } - db->aDb[0].zName = "main"; - db->aDb[1].zName = "temp"; - - /* 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].safety_level = 3; - db->aDb[1].safety_level = 1; - - /* 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; - 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 */ diff --git a/sqlite/src/os.h b/sqlite/src/os.h deleted file mode 100644 index d39d62d..0000000 --- a/sqlite/src/os.h +++ /dev/null @@ -1,182 +0,0 @@ -/* -** 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) -# 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 - -/* -** 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); -int sqlite3OsRandomSeed(char*); -int sqlite3OsSleep(int ms); -int sqlite3OsCurrentTime(double*); -int sqlite3OsFileModTime(OsFile*, double*); -void sqlite3OsEnterMutex(void); -void sqlite3OsLeaveMutex(void); -char *sqlite3OsFullPathname(const char*); -int sqlite3OsLock(OsFile*, int); -int sqlite3OsUnlock(OsFile*, int); -int sqlite3OsCheckReservedLock(OsFile *id); - -#endif /* _SQLITE_OS_H_ */ diff --git a/sqlite/src/os_test.c b/sqlite/src/os_test.c deleted file mode 100644 index 8199f5b..0000000 --- a/sqlite/src/os_test.c +++ /dev/null @@ -1,463 +0,0 @@ -/* -** 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. It is used -** for testing SQLite only. -*/ -#if OS_TEST /* This file is used for the test backend only */ -#include "sqliteInt.h" -#include "os.h" /* Must be first to enable large file support */ - -#define sqlite3OsOpenReadWrite sqlite3RealOpenReadWrite -#define sqlite3OsOpenExclusive sqlite3RealOpenExclusive -#define sqlite3OsOpenReadOnly sqlite3RealOpenReadOnly -#define sqlite3OsOpenDirectory sqlite3RealOpenDirectory -#define sqlite3OsClose sqlite3RealClose -#define sqlite3OsRead sqlite3RealRead -#define sqlite3OsWrite sqlite3RealWrite -#define sqlite3OsSeek sqlite3RealSeek -#define sqlite3OsSync sqlite3RealSync -#define sqlite3OsTruncate sqlite3RealTruncate -#define sqlite3OsFileSize sqlite3RealFileSize -#define sqlite3OsLock sqlite3RealLock -#define sqlite3OsUnlock sqlite3RealUnlock -#define sqlite3OsCheckReservedLock sqlite3RealCheckReservedLock - -#define OsFile OsRealFile -#define OS_UNIX 1 -#include "os_unix.c" -#undef OS_UNIX -#undef OsFile - -#undef sqlite3OsOpenReadWrite -#undef sqlite3OsOpenExclusive -#undef sqlite3OsOpenReadOnly -#undef sqlite3OsOpenDirectory -#undef sqlite3OsClose -#undef sqlite3OsRead -#undef sqlite3OsWrite -#undef sqlite3OsSeek -#undef sqlite3OsSync -#undef sqlite3OsTruncate -#undef sqlite3OsFileSize -#undef sqlite3OsLock -#undef sqlite3OsUnlock -#undef sqlite3OsCheckReservedLock - -#define BLOCKSIZE 512 -#define BLOCK_OFFSET(x) ((x) * BLOCKSIZE) - - -/* -** The following variables control when a simulated crash occurs. -** -** If iCrashDelay is non-zero, then zCrashFile contains (full path) name of -** a file that SQLite will call sqlite3OsSync() on. Each time this happens -** iCrashDelay is decremented. If iCrashDelay is zero after being -** decremented, a "crash" occurs during the sync() operation. -** -** In other words, a crash occurs the iCrashDelay'th time zCrashFile is -** synced. -*/ -static int iCrashDelay = 0; -char zCrashFile[256]; - -/* -** Set the value of the two crash parameters. -*/ -void sqlite3SetCrashParams(int iDelay, char const *zFile){ - sqlite3OsEnterMutex(); - assert( strlen(zFile)<256 ); - strcpy(zCrashFile, zFile); - iCrashDelay = iDelay; - sqlite3OsLeaveMutex(); -} - -/* -** File zPath is being sync()ed. Return non-zero if this should -** cause a crash. -*/ -static int crashRequired(char const *zPath){ - int r; - int n; - sqlite3OsEnterMutex(); - n = strlen(zCrashFile); - if( zCrashFile[n-1]=='*' ){ - n--; - }else if( strlen(zPath)>n ){ - n = strlen(zPath); - } - r = 0; - if( iCrashDelay>0 && strncmp(zPath, zCrashFile, n)==0 ){ - iCrashDelay--; - if( iCrashDelay<=0 ){ - r = 1; - } - } - sqlite3OsLeaveMutex(); - return r; -} - - -static OsTestFile *pAllFiles = 0; - -/* -** Initialise the os_test.c specific fields of pFile. -*/ -static void initFile(OsFile *id, char const *zName){ - OsTestFile *pFile = (OsTestFile *) - sqliteMalloc(sizeof(OsTestFile) + strlen(zName)+1); - pFile->nMaxWrite = 0; - pFile->nBlk = 0; - pFile->apBlk = 0; - pFile->zName = (char *)(&pFile[1]); - strcpy(pFile->zName, zName); - *id = pFile; - pFile->pNext = pAllFiles; - pAllFiles = pFile; -} - -/* -** Undo the work done by initFile. Delete the OsTestFile structure -** and unlink the structure from the pAllFiles list. -*/ -static void closeFile(OsFile *id){ - OsTestFile *pFile = *id; - if( pFile==pAllFiles ){ - pAllFiles = pFile->pNext; - }else{ - OsTestFile *p; - for(p=pAllFiles; p->pNext!=pFile; p=p->pNext ){ - assert( p ); - } - p->pNext = pFile->pNext; - } - sqliteFree(pFile); - *id = 0; -} - -/* -** Return the current seek offset from the start of the file. This -** is unix-only code. -*/ -static i64 osTell(OsTestFile *pFile){ - return lseek(pFile->fd.h, 0, SEEK_CUR); -} - -/* -** Load block 'blk' into the cache of pFile. -*/ -static int cacheBlock(OsTestFile *pFile, int blk){ - if( blk>=pFile->nBlk ){ - int n = ((pFile->nBlk * 2) + 100 + blk); - /* if( pFile->nBlk==0 ){ printf("DIRTY %s\n", pFile->zName); } */ - pFile->apBlk = (u8 **)sqliteRealloc(pFile->apBlk, n * sizeof(u8*)); - if( !pFile->apBlk ) return SQLITE_NOMEM; - memset(&pFile->apBlk[pFile->nBlk], 0, (n - pFile->nBlk)*sizeof(u8*)); - pFile->nBlk = n; - } - - if( !pFile->apBlk[blk] ){ - i64 filesize; - int rc; - - u8 *p = sqliteMalloc(BLOCKSIZE); - if( !p ) return SQLITE_NOMEM; - pFile->apBlk[blk] = p; - - rc = sqlite3RealFileSize(&pFile->fd, &filesize); - if( rc!=SQLITE_OK ) return rc; - - if( BLOCK_OFFSET(blk)fd, blk*BLOCKSIZE); - if( BLOCK_OFFSET(blk+1)>filesize ){ - len = filesize - BLOCK_OFFSET(blk); - } - if( rc!=SQLITE_OK ) return rc; - rc = sqlite3RealRead(&pFile->fd, p, len); - if( rc!=SQLITE_OK ) return rc; - } - } - - return SQLITE_OK; -} - -/* #define TRACE_WRITECACHE */ - -/* -** Write the cache of pFile to disk. If crash is non-zero, randomly -** skip blocks when writing. The cache is deleted before returning. -*/ -static int writeCache2(OsTestFile *pFile, int crash){ - int i; - int nMax = pFile->nMaxWrite; - i64 offset; - int rc = SQLITE_OK; - - offset = osTell(pFile); - for(i=0; inBlk; i++){ - u8 *p = pFile->apBlk[i]; - if( p ){ - int skip = 0; - int trash = 0; - if( crash ){ - char random; - sqlite3Randomness(1, &random); - if( random & 0x01 ){ - if( random & 0x02 ){ - trash = 1; -#ifdef TRACE_WRITECACHE -printf("Trashing block %d of %s\n", i, pFile->zName); -#endif - }else{ - skip = 1; -#ifdef TRACE_WRITECACHE -printf("Skiping block %d of %s\n", i, pFile->zName); -#endif - } - }else{ -#ifdef TRACE_WRITECACHE -printf("Writing block %d of %s\n", i, pFile->zName); -#endif - } - } - if( rc==SQLITE_OK ){ - rc = sqlite3RealSeek(&pFile->fd, BLOCK_OFFSET(i)); - } - if( rc==SQLITE_OK && !skip ){ - int len = BLOCKSIZE; - if( BLOCK_OFFSET(i+1)>nMax ){ - len = nMax-BLOCK_OFFSET(i); - } - if( len>0 ){ - if( trash ){ - sqlite3Randomness(len, p); - } - rc = sqlite3RealWrite(&pFile->fd, p, len); - } - } - sqliteFree(p); - } - } - sqliteFree(pFile->apBlk); - pFile->nBlk = 0; - pFile->apBlk = 0; - pFile->nMaxWrite = 0; - - if( rc==SQLITE_OK ){ - rc = sqlite3RealSeek(&pFile->fd, offset); - } - return rc; -} - -/* -** Write the cache to disk. -*/ -static int writeCache(OsTestFile *pFile){ - if( pFile->apBlk ){ - int c = crashRequired(pFile->zName); - if( c ){ - OsTestFile *p; -#ifdef TRACE_WRITECACHE - printf("\nCrash during sync of %s\n", pFile->zName); -#endif - for(p=pAllFiles; p; p=p->pNext){ - writeCache2(p, 1); - } - exit(-1); - }else{ - return writeCache2(pFile, 0); - } - } - return SQLITE_OK; -} - -/* -** Close the file. -*/ -int sqlite3OsClose(OsFile *id){ - if( !(*id) ) return SQLITE_OK; - if( (*id)->fd.isOpen ){ - /* printf("CLOSE %s (%d blocks)\n", (*id)->zName, (*id)->nBlk); */ - writeCache(*id); - sqlite3RealClose(&(*id)->fd); - } - closeFile(id); - return SQLITE_OK; -} - -int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ - i64 offset; /* The current offset from the start of the file */ - i64 end; /* The byte just past the last byte read */ - int blk; /* Block number the read starts on */ - int i; - u8 *zCsr; - int rc = SQLITE_OK; - OsTestFile *pFile = *id; - - offset = osTell(pFile); - end = offset+amt; - blk = (offset/BLOCKSIZE); - - zCsr = (u8 *)pBuf; - for(i=blk; i*BLOCKSIZE end ){ - len = len - (BLOCK_OFFSET(i+1)-end); - } - - if( inBlk && pFile->apBlk[i]){ - u8 *pBlk = pFile->apBlk[i]; - memcpy(zCsr, &pBlk[off], len); - }else{ - rc = sqlite3RealSeek(&pFile->fd, BLOCK_OFFSET(i) + off); - if( rc!=SQLITE_OK ) return rc; - rc = sqlite3RealRead(&pFile->fd, zCsr, len); - if( rc!=SQLITE_OK ) return rc; - } - - zCsr += len; - } - assert( zCsr==&((u8 *)pBuf)[amt] ); - - rc = sqlite3RealSeek(&pFile->fd, end); - return rc; -} - -int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ - i64 offset; /* The current offset from the start of the file */ - i64 end; /* The byte just past the last byte written */ - int blk; /* Block number the write starts on */ - int i; - const u8 *zCsr; - int rc = SQLITE_OK; - OsTestFile *pFile = *id; - - offset = osTell(pFile); - end = offset+amt; - blk = (offset/BLOCKSIZE); - - zCsr = (u8 *)pBuf; - for(i=blk; i*BLOCKSIZEapBlk[i]; - assert( pBlk ); - - if( BLOCK_OFFSET(i) < offset ){ - off = offset-BLOCK_OFFSET(i); - } - len = BLOCKSIZE - off; - if( BLOCK_OFFSET(i+1) > end ){ - len = len - (BLOCK_OFFSET(i+1)-end); - } - memcpy(&pBlk[off], zCsr, len); - zCsr += len; - } - if( pFile->nMaxWritenMaxWrite = end; - } - assert( zCsr==&((u8 *)pBuf)[amt] ); - - rc = sqlite3RealSeek(&pFile->fd, end); - return rc; -} - -/* -** Sync the file. First flush the write-cache to disk, then call the -** real sync() function. -*/ -int sqlite3OsSync(OsFile *id){ - int rc; - /* printf("SYNC %s (%d blocks)\n", (*id)->zName, (*id)->nBlk); */ - rc = writeCache(*id); - if( rc!=SQLITE_OK ) return rc; - rc = sqlite3RealSync(&(*id)->fd); - return rc; -} - -/* -** Truncate the file. Set the internal OsFile.nMaxWrite variable to the new -** file size to ensure that nothing in the write-cache past this point -** is written to disk. -*/ -int sqlite3OsTruncate(OsFile *id, i64 nByte){ - (*id)->nMaxWrite = nByte; - return sqlite3RealTruncate(&(*id)->fd, nByte); -} - -/* -** Return the size of the file. If the cache contains a write that extended -** the file, then return this size instead of the on-disk size. -*/ -int sqlite3OsFileSize(OsFile *id, i64 *pSize){ - int rc = sqlite3RealFileSize(&(*id)->fd, pSize); - if( rc==SQLITE_OK && pSize && *pSize<(*id)->nMaxWrite ){ - *pSize = (*id)->nMaxWrite; - } - return rc; -} - -/* -** The three functions used to open files. All that is required is to -** initialise the os_test.c specific fields and then call the corresponding -** os_unix.c function to really open the file. -*/ -int sqlite3OsOpenReadWrite(const char *zFilename, OsFile *id, int *pReadonly){ - initFile(id, zFilename); - return sqlite3RealOpenReadWrite(zFilename, &(*id)->fd, pReadonly); -} -int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ - initFile(id, zFilename); - return sqlite3RealOpenExclusive(zFilename, &(*id)->fd, delFlag); -} -int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){ - initFile(id, zFilename); - return sqlite3RealOpenReadOnly(zFilename, &(*id)->fd); -} - -/* -** These six function calls are passed straight through to the os_unix.c -** backend. -*/ -int sqlite3OsSeek(OsFile *id, i64 offset){ - return sqlite3RealSeek(&(*id)->fd, offset); -} -int sqlite3OsCheckReservedLock(OsFile *id){ - return sqlite3RealCheckReservedLock(&(*id)->fd); -} -int sqlite3OsLock(OsFile *id, int locktype){ - return sqlite3RealLock(&(*id)->fd, locktype); -} -int sqlite3OsUnlock(OsFile *id, int locktype){ - return sqlite3RealUnlock(&(*id)->fd, locktype); -} -int sqlite3OsOpenDirectory(const char *zDirname, OsFile *id){ - return sqlite3RealOpenDirectory(zDirname, &(*id)->fd); -} - -#endif /* OS_TEST */ diff --git a/sqlite/src/os_unix.c b/sqlite/src/os_unix.c deleted file mode 100644 index 0e270c0..0000000 --- a/sqlite/src/os_unix.c +++ /dev/null @@ -1,1309 +0,0 @@ -/* -** 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 -#include -#include -#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 -# 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, 0644); - 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, 0644); - 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; iisOpen ); - SimulateIOError(SQLITE_IOERR); - TIMER_START; - got = read(id->h, pBuf, amt); - TIMER_END; - TRACE4("READ %-3d %7d %d\n", id->h, 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; - TRACE4("WRITE %-3d %7d %d\n", id->h, 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; -} - -/* -** The fsync() system call does not work as advertised on many -** unix systems. The following procedure is an attempt to make -** it work better. -** -** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful -** for testing when we want to run through the test suite quickly. -** You are strongly advised *not* to deploy with SQLITE_NO_SYNC -** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash -** or power failure will likely corrupt the database file. -*/ -static int full_fsync(int fd){ -#ifdef SQLITE_NO_SYNC - return SQLITE_OK; -#else - int rc; -#ifdef F_FULLFSYNC - rc = fcntl(fd, F_FULLFSYNC, 0); - if( rc ) rc = fsync(fd); -#else - rc = fsync(fd); -#endif - return rc; -#endif -} - -/* -** 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) ){ - return SQLITE_IOERR; - } - if( id->dirfd>=0 ){ - TRACE2("DIRSYNC %-3d\n", id->dirfd); - full_fsync(id->dirfd); - 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. -*/ -int sqlite3OsSyncDirectory(const char *zDirname){ - int fd; - int r; - SimulateIOError(SQLITE_IOERR); - fd = open(zDirname, O_RDONLY|O_BINARY, 0644); - 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->locktypeh, 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; inPending; 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; -} - -/* -** 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 -} - -/* -** 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]; - sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative, - (char*)0); - } - return zFull; -} - -/* -** 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; -} - -#if 0 /* NOT USED */ -/* -** Find the time that the file was last modified. Write the -** modification time and date as a Julian Day number into *prNow and -** return SQLITE_OK. Return SQLITE_ERROR if the modification -** time cannot be found. -*/ -int sqlite3OsFileModTime(OsFile *id, double *prNow){ - int rc; - struct stat statbuf; - if( fstat(id->h, &statbuf)==0 ){ - *prNow = statbuf.st_mtime/86400.0 + 2440587.5; - rc = SQLITE_OK; - }else{ - rc = SQLITE_ERROR; - } - return rc; -} -#endif /* NOT USED */ - -#endif /* OS_UNIX */ diff --git a/sqlite/src/os_win.c b/sqlite/src/os_win.c deleted file mode 100644 index 2614ed0..0000000 --- a/sqlite/src/os_win.c +++ /dev/null @@ -1,766 +0,0 @@ -/* -** 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 - -/* -** 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" - -/* -** 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; -} - -/* -** 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 -} - -/* -** 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; - nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1; - zFull = sqliteMalloc( nByte ); - if( zFull==0 ) return 0; - GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed); - return zFull; -} - -/* -** 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; -} - -/* -** Find the time that the file was last modified. Write the -** modification time and date as a Julian Day number into *prNow and -** return SQLITE_OK. Return SQLITE_ERROR if the modification -** time cannot be found. -*/ -int sqlite3OsFileModTime(OsFile *id, double *prMTime){ - int rc; - FILETIME ft; - /* FILETIME structure is a 64-bit value representing the number of - ** 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). - */ - if( GetFileTime(id->h, 0, 0, &ft) ){ - double t; - t = ((double)ft.dwHighDateTime) * 4294967296.0; - *prMTime = (t + ft.dwLowDateTime)/864000000000.0 + 2305813.5; - rc = SQLITE_OK; - }else{ - rc = SQLITE_ERROR; - } - return rc; -} - -#endif /* OS_WIN */ diff --git a/sqlite/src/pager.c b/sqlite/src/pager.c deleted file mode 100644 index 4a65af7..0000000 --- a/sqlite/src/pager.c +++ /dev/null @@ -1,3519 +0,0 @@ -/* -** 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.190 2005/02/15 03:38:06 danielk1977 Exp $ -*/ -#include "sqliteInt.h" -#include "os.h" -#include "pager.h" -#include -#include - -/* -** 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->psAligned 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)->psAligned]) -#define PGHDR_TO_HIST(P,PGR) \ - ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->psAligned+(PGR)->nExtra]) - -/* -** How big to make the hash table used for locating in-memory pages -** by page number. -*/ -#define N_PG_HASH 2048 - -/* -** 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 { - 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*/ - 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() */ - i64 stmtJSize; /* Size of journal 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 */ - void (*xDestructor)(void*,int); /* Call this routine when freeing pages */ - void (*xReiniter)(void*,int); /* Call this routine when reloading pages */ - int pageSize; /* Number of bytes in a page */ - int psAligned; /* pageSize rounded up to a multiple of 8 */ - int nPage; /* Total number of in-memory pages */ - int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */ - int mxPage; /* Maximum number of pages to hold in cache */ - int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */ - int nRead,nWrite; /* Database pages read/written */ - void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ - void *pCodecArg; /* First argument to xCodec() */ - u8 journalOpen; /* True if journal file descriptors is valid */ - u8 journalStarted; /* True if header of journal is synced */ - u8 useJournal; /* Use a rollback journal on this file */ - u8 noReadlock; /* Do not bother to obtain readlocks */ - u8 stmtOpen; /* True if the statement subjournal is open */ - u8 stmtInUse; /* True we are in a statement subtransaction */ - u8 stmtAutoopen; /* Open stmt journal when main journal is opened*/ - 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 *aInJournal; /* One bit for each page in the database file */ - u8 *aInStmt; /* One bit for each page in the database */ - u8 setMaster; /* True if a m-j name has been written to jrnl */ - 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 */ - int sectorSize; /* Assumed sector size during rollback */ - PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number to PgHdr */ -}; - -/* -** 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; ipPager->pageSize; i++){ - hash = (hash+i)^pData[i]; - } - return hash; -} - -/* -** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES -** is defined, and NDEBUG is not defined, an assert() statement checks -** that the page is either dirty or still matches the calculated page-hash. -*/ -#define CHECK_PAGE(x) checkPage(x) -static void checkPage(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - assert( !pPg->pageHash || pPager->errMask || MEMDB || pPg->dirty || - pPg->pageHash==pager_pagehash(pPg) ); -} - -#else -#define CHECK_PAGE(x) -#endif - -/* -** When this is called the journal file for pager pPager must be open. -** The master journal file name is read from the end of the file and -** 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; ijournalOff; - 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)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; ifullSync ){ - 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; - 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 ); -} - -/* -** 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->statestmtOpen ){ - 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->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 */ - - 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. - */ - pPg = pager_lookup(pPager, pgno); - assert( pPager->state>=PAGER_EXCLUSIVE || pPg ); - TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno); - if( pPager->state>=PAGER_EXCLUSIVE ){ - sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); - rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize); - } - if( pPg ){ - /* No page should ever be 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); - } - if( pPager->state>=PAGER_EXCLUSIVE ){ - pPg->dirty = 0; - pPg->needSync = 0; -#ifdef SQLITE_CHECK_PAGES - pPg->pageHash = pager_pagehash(pPg); -#endif - } - CODEC(pPager, pData, pPg->pgno, 3); - } - 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)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; ijfd, 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. -** -** The maximum number is the absolute value of the mxPage parameter. -** If mxPage is negative, the noSync flag is also set. noSync bypasses -** calls to sqlite3OsSync(). The pager runs much faster with noSync on, -** but if the operating system crashes or there is an abrupt power -** failure, the database file might be left in an inconsistent and -** unrepairable state. -*/ -void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){ - if( mxPage>=0 ){ - pPager->noSync = pPager->tempFile; - if( pPager->noSync ) pPager->needSync = 0; - }else{ - pPager->noSync = 1; - mxPage = -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 - -/* -** Open a temporary file. Write the name of the file into zName -** (zName 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; - 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->psAligned = FORCE_ALIGNMENT(pPager->pageSize); - pPager->stmtSize = 0; - pPager->stmtJSize = 0; - pPager->nPage = 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. -** -** The page size must only be changed when the cache is empty. -*/ -void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){ - assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ); - pPager->pageSize = pageSize; - pPager->psAligned = FORCE_ALIGNMENT(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; - do { - rc = sqlite3OsLock(&pPager->fd, locktype); - }while( rc==SQLITE_BUSY && - pPager->pBusyHandler && - pPager->pBusyHandler->xFunc && - pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++) - ); - if( rc==SQLITE_OK ){ - pPager->state = locktype; - } - } - return rc; -} - -/* -** Truncate the file to the number of pages specified. -*/ -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->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)); - sqlite3OsClose(&pPager->fd); - assert( pPager->journalOpen==0 ); - /* 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); - 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; -} - -/* -** 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, n; - - /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page - ** number greater than this, or zero, is requested. - */ - if( pgno>PAGER_MAX_PGNO || pgno==0 ){ - return SQLITE_CORRUPT; - } - - /* Make sure we have not hit any critical errors. - */ - assert( pPager!=0 ); - *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( pPager->useJournal && - sqlite3OsFileExists(pPager->zJournal) && - !sqlite3OsCheckReservedLock(&pPager->fd) - ){ - 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; - pPager->nMiss++; - if( pPager->nPagemxPage || pPager->pFirst==0 || MEMDB ){ - /* Create a new page */ - pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->psAligned - + sizeof(u32) + pPager->nExtra - + MEMDB*sizeof(PgHistory) ); - if( pPg==0 ){ - if( !MEMDB ){ - pager_unwritelock(pPager); - } - 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++; - }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); - 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); - } - n = sqlite3pager_pagecount(pPager); - if( pPager->errMask!=0 ){ - sqlite3pager_unref(PGHDR_TO_DATA(pPg)); - rc = pager_errcode(pPager); - return rc; - } - if( n<(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{ - pPager->nRead++; - } - } -#ifdef SQLITE_CHECK_PAGES - pPg->pageHash = pager_pagehash(pPg); -#endif - }else{ - /* The requested page is in the page cache. */ - 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 ); - 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; - } - 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); - return rc; - } - 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{ - if( SQLITE_BUSY_RESERVED_LOCK || exFlag ){ - rc = pager_wait_on_lock(pPager, RESERVED_LOCK); - }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->origDbSizedbSize ){ - /* 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->statedirty = 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; - a[6] = pPager->nHit; - a[7] = pPager->nMiss; - a[8] = pPager->nOvfl; - a[9] = pPager->nRead; - a[10] = pPager->nWrite; - 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, however it is -** illegal to call this routine if a statment transaction is active. -*/ -int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){ - PgHdr *pPg = DATA_TO_PGHDR(pData); - PgHdr *pPgOld; - int h; - Pgno needSyncPgno = 0; - - assert( !pPager->stmtInUse ); - assert( pPg->nRef>0 ); - - TRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", - PAGERID(pPager), pPg->pgno, pPg->needSync, pgno); - - if( pPg->needSync ){ - needSyncPgno = pPg->pgno; - assert( pPg->inJournal ); - assert( pPg->dirty ); - assert( pPager->needSync ); - } - - /* Unlink pPg from it's hash-chain */ - unlinkHashChain(pPager, pPg); - - /* If the cache contains a page with page-number pgno, remove it - ** from it's hash chain. Also, if the PgHdr.needSync was set for - ** page pgno before the 'move' operation, it needs to be retained - ** for the page moved there. - */ - pPgOld = pager_lookup(pPager, pgno); - if( pPgOld ){ - assert( pPgOld->nRef==0 ); - unlinkHashChain(pPager, pPgOld); - pPgOld->dirty = 0; - if( pPgOld->needSync ){ - assert( pPgOld->inJournal ); - pPg->inJournal = 1; - pPg->needSync = 1; - assert( pPager->needSync ); - } - } - - /* Change the page number for pPg and insert it into the new hash-chain. */ - pPg->pgno = pgno; - h = pager_hash(pgno); - if( pPager->aHash[h] ){ - assert( pPager->aHash[h]->pPrevHash==0 ); - pPager->aHash[h]->pPrevHash = pPg; - } - pPg->pNextHash = pPager->aHash[h]; - pPager->aHash[h] = pPg; - pPg->pPrevHash = 0; - - pPg->dirty = 1; - pPager->dirtyCache = 1; - - if( needSyncPgno ){ - /* If needSyncPgno is non-zero, then the journal file needs to be - ** sync()ed before any data is written to database file page needSyncPgno. - ** Currently, no such page exists in the page-cache and the - ** Pager.aInJournal bit has been set. This needs to be remedied by loading - ** the page into the pager-cache and setting the PgHdr.needSync flag. - ** - ** The sqlite3pager_get() call may cause the journal to sync. So make - ** sure the Pager.needSync flag is set too. - */ - int rc; - void *pNeedSync; - assert( pPager->needSync ); - rc = sqlite3pager_get(pPager, needSyncPgno, &pNeedSync); - if( rc!=SQLITE_OK ) return rc; - pPager->needSync = 1; - DATA_TO_PGHDR(pNeedSync)->needSync = 1; - DATA_TO_PGHDR(pNeedSync)->inJournal = 1; - DATA_TO_PGHDR(pNeedSync)->dirty = 1; - sqlite3pager_unref(pNeedSync); - } - - return SQLITE_OK; -} -#endif - -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) -/* -** Return the current state of the file lock for the given pager. -** 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 diff --git a/sqlite/src/pager.h b/sqlite/src/pager.h deleted file mode 100644 index 8e88c86..0000000 --- a/sqlite/src/pager.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -** 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.41 2005/02/06 02:45:42 drh 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 65536 (a limit -** imposed by the 2-byte size of cell array pointers.) The -** maximum page size determines the amount of stack space allocated -** by many of the routines in pager.c and btree.c On embedded architectures -** or any machine where memory and especially stack memory is limited, -** one may wish to chose a smaller value for the maximum page size. -*/ -#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)); -void 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); - -#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/sqlite/src/parse.y b/sqlite/src/parse.y deleted file mode 100644 index 2ad78de..0000000 --- a/sqlite/src/parse.y +++ /dev/null @@ -1,971 +0,0 @@ -/* -** 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 SQLite's grammar for SQL. Process this file -** using the lemon parser generator to generate C code that runs -** the parser. Lemon will also generate a header file containing -** numeric codes for all of the tokens. -** -** @(#) $Id: parse.y,v 1.166 2005/02/14 06:38:40 danielk1977 Exp $ -*/ -%token_prefix TK_ -%token_type {Token} -%default_type {Token} -%extra_argument {Parse *pParse} -%syntax_error { - if( pParse->zErrMsg==0 ){ - if( TOKEN.z[0] ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); - }else{ - sqlite3ErrorMsg(pParse, "incomplete SQL statement"); - } - } -} -%name sqlite3Parser -%include { -#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 { - int opcode; /* Either TK_GLOB or TK_LIKE */ - 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; }; - -} // end %include - -// These are extra tokens used by the lexer but never seen by the -// parser. We put them in a rule so that the parser generator will -// add them to the parse.h output file. -// -%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION - COLUMN AGG_FUNCTION. - -// Input is a single SQL command -input ::= cmdlist. -cmdlist ::= cmdlist ecmd. -cmdlist ::= ecmd. -cmdx ::= cmd. { sqlite3FinishCoding(pParse); } -ecmd ::= SEMI. -ecmd ::= explain cmdx SEMI. -explain ::= . { sqlite3BeginParse(pParse, 0); } -%ifndef SQLITE_OMIT_EXPLAIN -explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); } -%endif - -///////////////////// Begin and end transactions. //////////////////////////// -// - -cmd ::= BEGIN transtype(Y) trans_opt. {sqlite3BeginTransaction(pParse, Y);} -trans_opt ::= . -trans_opt ::= TRANSACTION. -trans_opt ::= TRANSACTION nm. -%type transtype {int} -transtype(A) ::= . {A = TK_DEFERRED;} -transtype(A) ::= DEFERRED(X). {A = @X;} -transtype(A) ::= IMMEDIATE(X). {A = @X;} -transtype(A) ::= EXCLUSIVE(X). {A = @X;} -cmd ::= COMMIT trans_opt. {sqlite3CommitTransaction(pParse);} -cmd ::= END trans_opt. {sqlite3CommitTransaction(pParse);} -cmd ::= ROLLBACK trans_opt. {sqlite3RollbackTransaction(pParse);} - -///////////////////// The CREATE TABLE statement //////////////////////////// -// -cmd ::= create_table create_table_args. -create_table ::= CREATE(X) temp(T) TABLE nm(Y) dbnm(Z). { - sqlite3StartTable(pParse,&X,&Y,&Z,T,0); -} -%type temp {int} -temp(A) ::= TEMP. {A = 1;} -temp(A) ::= . {A = 0;} -create_table_args ::= LP columnlist conslist_opt RP(X). { - sqlite3EndTable(pParse,&X,0); -} -create_table_args ::= AS select(S). { - sqlite3EndTable(pParse,0,S); - sqlite3SelectDelete(S); -} -columnlist ::= columnlist COMMA column. -columnlist ::= column. - -// About the only information used for a column is the name of the -// column. The type is always just "text". But the code will accept -// an elaborate typename. Perhaps someday we'll do something with it. -// -column ::= columnid type carglist. -columnid ::= nm(X). {sqlite3AddColumn(pParse,&X);} - -// An IDENTIFIER can be a generic identifier, or one of several -// keywords. Any non-standard keyword can also be an identifier. -// -%type id {Token} -id(A) ::= ID(X). {A = X;} - -// The following directive causes tokens ABORT, AFTER, ASC, etc. to -// fallback to ID if they will not parse as their original value. -// This obviates the need for the "id" nonterminal. -// -%fallback ID - ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CONFLICT - DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR - GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY - OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT - TEMP TRIGGER VACUUM VIEW -%ifdef SQLITE_OMIT_COMPOUND_SELECT - EXCEPT INTERSECT UNION -%endif - REINDEX RENAME CDATE CTIME CTIMESTAMP ALTER - . - -// Define operator precedence early so that this is the first occurance -// of the operator tokens in the grammer. Keeping the operators together -// causes them to be assigned integer values that are close together, -// which keeps parser tables smaller. -// -// The token values assigned to these symbols is determined by the order -// in which lemon first sees them. It must be the case that ISNULL/NOTNULL, -// NE/EQ, GT/LE, and GE/LT are separated by only a single value. See -// the sqlite3ExprIfFalse() routine for additional information on this -// constraint. -// -%left OR. -%left AND. -%right NOT. -%left IS LIKE GLOB BETWEEN IN ISNULL NOTNULL NE EQ. -%left GT LE LT GE. -%right ESCAPE. -%left BITAND BITOR LSHIFT RSHIFT. -%left PLUS MINUS. -%left STAR SLASH REM. -%left CONCAT. -%right UMINUS UPLUS BITNOT. - -// And "ids" is an identifer-or-string. -// -%type ids {Token} -ids(A) ::= ID(X). {A = X;} -ids(A) ::= STRING(X). {A = X;} - -// The name of a column or table can be any of the following: -// -%type nm {Token} -nm(A) ::= ID(X). {A = X;} -nm(A) ::= STRING(X). {A = X;} -nm(A) ::= JOIN_KW(X). {A = X;} - -type ::= . -type ::= typename(X). {sqlite3AddColumnType(pParse,&X,&X);} -type ::= typename(X) LP signed RP(Y). {sqlite3AddColumnType(pParse,&X,&Y);} -type ::= typename(X) LP signed COMMA signed RP(Y). - {sqlite3AddColumnType(pParse,&X,&Y);} -%type typename {Token} -typename(A) ::= ids(X). {A = X;} -typename(A) ::= typename(X) ids(Y). {A.z=X.z; A.n=Y.n+(Y.z-X.z);} -%type signed {int} -signed(A) ::= plus_num(X). { A = atoi(X.z); } -signed(A) ::= minus_num(X). { A = -atoi(X.z); } -carglist ::= carglist carg. -carglist ::= . -carg ::= CONSTRAINT nm ccons. -carg ::= ccons. -carg ::= DEFAULT term(X). {sqlite3AddDefaultValue(pParse,X);} -carg ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,X);} -carg ::= DEFAULT MINUS term(X). { - Expr *p = sqlite3Expr(TK_UMINUS, X, 0, 0); - sqlite3AddDefaultValue(pParse,p); -} -carg ::= DEFAULT id(X). { - Expr *p = sqlite3Expr(TK_STRING, 0, 0, &X); - sqlite3AddDefaultValue(pParse,p); -} - -// In addition to the type name, we also care about the primary key and -// UNIQUE constraints. -// -ccons ::= NULL onconf. -ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);} -ccons ::= PRIMARY KEY sortorder onconf(R) autoinc(I). - {sqlite3AddPrimaryKey(pParse,0,R,I);} -ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0);} -ccons ::= CHECK LP expr RP onconf. -ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R). - {sqlite3CreateForeignKey(pParse,0,&T,TA,R);} -ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);} -ccons ::= COLLATE id(C). {sqlite3AddCollateType(pParse, C.z, C.n);} - -// The optional AUTOINCREMENT keyword -%type autoinc {int} -autoinc(X) ::= . {X = 0;} -autoinc(X) ::= AUTOINCR. {X = 1;} - -// The next group of rules parses the arguments to a REFERENCES clause -// that determine if the referential integrity checking is deferred or -// or immediate and which determine what action to take if a ref-integ -// check fails. -// -%type refargs {int} -refargs(A) ::= . { A = OE_Restrict * 0x010101; } -refargs(A) ::= refargs(X) refarg(Y). { A = (X & Y.mask) | Y.value; } -%type refarg {struct {int value; int mask;}} -refarg(A) ::= MATCH nm. { A.value = 0; A.mask = 0x000000; } -refarg(A) ::= ON DELETE refact(X). { A.value = X; A.mask = 0x0000ff; } -refarg(A) ::= ON UPDATE refact(X). { A.value = X<<8; A.mask = 0x00ff00; } -refarg(A) ::= ON INSERT refact(X). { A.value = X<<16; A.mask = 0xff0000; } -%type refact {int} -refact(A) ::= SET NULL. { A = OE_SetNull; } -refact(A) ::= SET DEFAULT. { A = OE_SetDflt; } -refact(A) ::= CASCADE. { A = OE_Cascade; } -refact(A) ::= RESTRICT. { A = OE_Restrict; } -%type defer_subclause {int} -defer_subclause(A) ::= NOT DEFERRABLE init_deferred_pred_opt(X). {A = X;} -defer_subclause(A) ::= DEFERRABLE init_deferred_pred_opt(X). {A = X;} -%type init_deferred_pred_opt {int} -init_deferred_pred_opt(A) ::= . {A = 0;} -init_deferred_pred_opt(A) ::= INITIALLY DEFERRED. {A = 1;} -init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE. {A = 0;} - -// For the time being, the only constraint we care about is the primary -// key and UNIQUE. Both create indices. -// -conslist_opt ::= . -conslist_opt ::= COMMA conslist. -conslist ::= conslist COMMA tcons. -conslist ::= conslist tcons. -conslist ::= tcons. -tcons ::= CONSTRAINT nm. -tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R). - {sqlite3AddPrimaryKey(pParse,X,R,I);} -tcons ::= UNIQUE LP idxlist(X) RP onconf(R). - {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0);} -tcons ::= CHECK expr onconf. -tcons ::= FOREIGN KEY LP idxlist(FA) RP - REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). { - sqlite3CreateForeignKey(pParse, FA, &T, TA, R); - sqlite3DeferForeignKey(pParse, D); -} -%type defer_subclause_opt {int} -defer_subclause_opt(A) ::= . {A = 0;} -defer_subclause_opt(A) ::= defer_subclause(X). {A = X;} - -// The following is a non-standard extension that allows us to declare the -// default behavior when there is a constraint conflict. -// -%type onconf {int} -%type orconf {int} -%type resolvetype {int} -onconf(A) ::= . {A = OE_Default;} -onconf(A) ::= ON CONFLICT resolvetype(X). {A = X;} -orconf(A) ::= . {A = OE_Default;} -orconf(A) ::= OR resolvetype(X). {A = X;} -resolvetype(A) ::= raisetype(X). {A = X;} -resolvetype(A) ::= IGNORE. {A = OE_Ignore;} -resolvetype(A) ::= REPLACE. {A = OE_Replace;} - -////////////////////////// The DROP TABLE ///////////////////////////////////// -// -cmd ::= DROP TABLE fullname(X). { - sqlite3DropTable(pParse, X, 0); -} - -///////////////////// The CREATE VIEW statement ///////////////////////////// -// -%ifndef SQLITE_OMIT_VIEW -cmd ::= CREATE(X) temp(T) VIEW nm(Y) dbnm(Z) AS select(S). { - sqlite3CreateView(pParse, &X, &Y, &Z, S, T); -} -cmd ::= DROP VIEW fullname(X). { - sqlite3DropTable(pParse, X, 1); -} -%endif // SQLITE_OMIT_VIEW - -//////////////////////// The SELECT statement ///////////////////////////////// -// -cmd ::= select(X). { - sqlite3Select(pParse, X, SRT_Callback, 0, 0, 0, 0, 0); - sqlite3SelectDelete(X); -} - -%type select {Select*} -%destructor select {sqlite3SelectDelete($$);} -%type oneselect {Select*} -%destructor oneselect {sqlite3SelectDelete($$);} - -select(A) ::= oneselect(X). {A = X;} -%ifndef SQLITE_OMIT_COMPOUND_SELECT -select(A) ::= select(X) multiselect_op(Y) oneselect(Z). { - if( Z ){ - Z->op = Y; - Z->pPrior = X; - } - A = Z; -} -%type multiselect_op {int} -multiselect_op(A) ::= UNION(OP). {A = @OP;} -multiselect_op(A) ::= UNION ALL. {A = TK_ALL;} -multiselect_op(A) ::= INTERSECT(OP). {A = @OP;} -multiselect_op(A) ::= EXCEPT(OP). {A = @OP;} -%endif // SQLITE_OMIT_COMPOUND_SELECT -oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) - groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { - A = sqlite3SelectNew(W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset); -} - -// The "distinct" nonterminal is true (1) if the DISTINCT keyword is -// present and false (0) if it is not. -// -%type distinct {int} -distinct(A) ::= DISTINCT. {A = 1;} -distinct(A) ::= ALL. {A = 0;} -distinct(A) ::= . {A = 0;} - -// selcollist is a list of expressions that are to become the return -// values of the SELECT statement. The "*" in statements like -// "SELECT * FROM ..." is encoded as a special expression with an -// opcode of TK_ALL. -// -%type selcollist {ExprList*} -%destructor selcollist {sqlite3ExprListDelete($$);} -%type sclp {ExprList*} -%destructor sclp {sqlite3ExprListDelete($$);} -sclp(A) ::= selcollist(X) COMMA. {A = X;} -sclp(A) ::= . {A = 0;} -selcollist(A) ::= sclp(P) expr(X) as(Y). { - A = sqlite3ExprListAppend(P,X,Y.n?&Y:0); -} -selcollist(A) ::= sclp(P) STAR. { - A = sqlite3ExprListAppend(P, sqlite3Expr(TK_ALL, 0, 0, 0), 0); -} -selcollist(A) ::= sclp(P) nm(X) DOT STAR. { - Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0); - Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &X); - A = sqlite3ExprListAppend(P, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); -} - -// An option "AS " phrase that can follow one of the expressions that -// define the result set, or one of the tables in the FROM clause. -// -%type as {Token} -as(X) ::= AS nm(Y). {X = Y;} -as(X) ::= ids(Y). {X = Y;} -as(X) ::= . {X.n = 0;} - - -%type seltablist {SrcList*} -%destructor seltablist {sqlite3SrcListDelete($$);} -%type stl_prefix {SrcList*} -%destructor stl_prefix {sqlite3SrcListDelete($$);} -%type from {SrcList*} -%destructor from {sqlite3SrcListDelete($$);} - -// A complete FROM clause. -// -from(A) ::= . {A = sqliteMalloc(sizeof(*A));} -from(A) ::= FROM seltablist(X). {A = X;} - -// "seltablist" is a "Select Table List" - the content of the FROM clause -// in a SELECT statement. "stl_prefix" is a prefix of this list. -// -stl_prefix(A) ::= seltablist(X) joinop(Y). { - A = X; - if( A && A->nSrc>0 ) A->a[A->nSrc-1].jointype = Y; -} -stl_prefix(A) ::= . {A = 0;} -seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). { - A = sqlite3SrcListAppend(X,&Y,&D); - if( Z.n ) sqlite3SrcListAddAlias(A,&Z); - if( N ){ - if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; } - else { sqlite3ExprDelete(N); } - } - if( U ){ - if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; } - else { sqlite3IdListDelete(U); } - } -} -%ifndef SQLITE_OMIT_SUBQUERY - seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP - as(Z) on_opt(N) using_opt(U). { - A = sqlite3SrcListAppend(X,0,0); - A->a[A->nSrc-1].pSelect = S; - if( Z.n ) sqlite3SrcListAddAlias(A,&Z); - if( N ){ - if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; } - else { sqlite3ExprDelete(N); } - } - if( U ){ - if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; } - else { sqlite3IdListDelete(U); } - } - } - - // A seltablist_paren nonterminal represents anything in a FROM that - // is contained inside parentheses. This can be either a subquery or - // a grouping of table and subqueries. - // - %type seltablist_paren {Select*} - %destructor seltablist_paren {sqlite3SelectDelete($$);} - seltablist_paren(A) ::= select(S). {A = S;} - seltablist_paren(A) ::= seltablist(F). { - A = sqlite3SelectNew(0,F,0,0,0,0,0,0,0); - } -%endif // SQLITE_OMIT_SUBQUERY - -%type dbnm {Token} -dbnm(A) ::= . {A.z=0; A.n=0;} -dbnm(A) ::= DOT nm(X). {A = X;} - -%type fullname {SrcList*} -%destructor fullname {sqlite3SrcListDelete($$);} -fullname(A) ::= nm(X) dbnm(Y). {A = sqlite3SrcListAppend(0,&X,&Y);} - -%type joinop {int} -%type joinop2 {int} -joinop(X) ::= COMMA. { X = JT_INNER; } -joinop(X) ::= JOIN. { X = JT_INNER; } -joinop(X) ::= JOIN_KW(A) JOIN. { X = sqlite3JoinType(pParse,&A,0,0); } -joinop(X) ::= JOIN_KW(A) nm(B) JOIN. { X = sqlite3JoinType(pParse,&A,&B,0); } -joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN. - { X = sqlite3JoinType(pParse,&A,&B,&C); } - -%type on_opt {Expr*} -%destructor on_opt {sqlite3ExprDelete($$);} -on_opt(N) ::= ON expr(E). {N = E;} -on_opt(N) ::= . {N = 0;} - -%type using_opt {IdList*} -%destructor using_opt {sqlite3IdListDelete($$);} -using_opt(U) ::= USING LP inscollist(L) RP. {U = L;} -using_opt(U) ::= . {U = 0;} - - -%type orderby_opt {ExprList*} -%destructor orderby_opt {sqlite3ExprListDelete($$);} -%type sortlist {ExprList*} -%destructor sortlist {sqlite3ExprListDelete($$);} -%type sortitem {Expr*} -%destructor sortitem {sqlite3ExprDelete($$);} - -orderby_opt(A) ::= . {A = 0;} -orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} -sortlist(A) ::= sortlist(X) COMMA sortitem(Y) collate(C) sortorder(Z). { - A = sqlite3ExprListAppend(X,Y,C.n>0?&C:0); - if( A ) A->a[A->nExpr-1].sortOrder = Z; -} -sortlist(A) ::= sortitem(Y) collate(C) sortorder(Z). { - A = sqlite3ExprListAppend(0,Y,C.n>0?&C:0); - if( A && A->a ) A->a[0].sortOrder = Z; -} -sortitem(A) ::= expr(X). {A = X;} - -%type sortorder {int} -%type collate {Token} - -sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;} -sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;} -sortorder(A) ::= . {A = SQLITE_SO_ASC;} -collate(C) ::= . {C.z = 0; C.n = 0;} -collate(C) ::= COLLATE id(X). {C = X;} - -%type groupby_opt {ExprList*} -%destructor groupby_opt {sqlite3ExprListDelete($$);} -groupby_opt(A) ::= . {A = 0;} -groupby_opt(A) ::= GROUP BY exprlist(X). {A = X;} - -%type having_opt {Expr*} -%destructor having_opt {sqlite3ExprDelete($$);} -having_opt(A) ::= . {A = 0;} -having_opt(A) ::= HAVING expr(X). {A = X;} - -%type limit_opt {struct LimitVal} -%destructor limit_opt { - sqlite3ExprDelete($$.pLimit); - sqlite3ExprDelete($$.pOffset); -} -limit_opt(A) ::= . {A.pLimit = 0; A.pOffset = 0;} -limit_opt(A) ::= LIMIT expr(X). {A.pLimit = X; A.pOffset = 0;} -limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). - {A.pLimit = X; A.pOffset = Y;} -limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). - {A.pOffset = X; A.pLimit = Y;} - -/////////////////////////// The DELETE statement ///////////////////////////// -// -cmd ::= DELETE FROM fullname(X) where_opt(Y). {sqlite3DeleteFrom(pParse,X,Y);} - -%type where_opt {Expr*} -%destructor where_opt {sqlite3ExprDelete($$);} - -where_opt(A) ::= . {A = 0;} -where_opt(A) ::= WHERE expr(X). {A = X;} - -%type setlist {ExprList*} -%destructor setlist {sqlite3ExprListDelete($$);} - -////////////////////////// The UPDATE command //////////////////////////////// -// -cmd ::= UPDATE orconf(R) fullname(X) SET setlist(Y) where_opt(Z). - {sqlite3Update(pParse,X,Y,Z,R);} - -setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y). - {A = sqlite3ExprListAppend(Z,Y,&X);} -setlist(A) ::= nm(X) EQ expr(Y). {A = sqlite3ExprListAppend(0,Y,&X);} - -////////////////////////// The INSERT command ///////////////////////////////// -// -cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) - VALUES LP itemlist(Y) RP. - {sqlite3Insert(pParse, X, Y, 0, F, R);} -cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S). - {sqlite3Insert(pParse, X, 0, S, F, R);} - -%type insert_cmd {int} -insert_cmd(A) ::= INSERT orconf(R). {A = R;} -insert_cmd(A) ::= REPLACE. {A = OE_Replace;} - - -%type itemlist {ExprList*} -%destructor itemlist {sqlite3ExprListDelete($$);} - -itemlist(A) ::= itemlist(X) COMMA expr(Y). {A = sqlite3ExprListAppend(X,Y,0);} -itemlist(A) ::= expr(X). {A = sqlite3ExprListAppend(0,X,0);} - -%type inscollist_opt {IdList*} -%destructor inscollist_opt {sqlite3IdListDelete($$);} -%type inscollist {IdList*} -%destructor inscollist {sqlite3IdListDelete($$);} - -inscollist_opt(A) ::= . {A = 0;} -inscollist_opt(A) ::= LP inscollist(X) RP. {A = X;} -inscollist(A) ::= inscollist(X) COMMA nm(Y). {A = sqlite3IdListAppend(X,&Y);} -inscollist(A) ::= nm(Y). {A = sqlite3IdListAppend(0,&Y);} - -/////////////////////////// Expression Processing ///////////////////////////// -// - -%type expr {Expr*} -%destructor expr {sqlite3ExprDelete($$);} -%type term {Expr*} -%destructor term {sqlite3ExprDelete($$);} - -expr(A) ::= term(X). {A = X;} -expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqlite3ExprSpan(A,&B,&E); } -term(A) ::= NULL(X). {A = sqlite3Expr(@X, 0, 0, &X);} -expr(A) ::= ID(X). {A = sqlite3Expr(TK_ID, 0, 0, &X);} -expr(A) ::= JOIN_KW(X). {A = sqlite3Expr(TK_ID, 0, 0, &X);} -expr(A) ::= nm(X) DOT nm(Y). { - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &X); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &Y); - A = sqlite3Expr(TK_DOT, temp1, temp2, 0); -} -expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &X); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &Y); - Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &Z); - Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); - A = sqlite3Expr(TK_DOT, temp1, temp4, 0); -} -term(A) ::= INTEGER(X). {A = sqlite3Expr(@X, 0, 0, &X);} -term(A) ::= FLOAT(X). {A = sqlite3Expr(@X, 0, 0, &X);} -term(A) ::= STRING(X). {A = sqlite3Expr(@X, 0, 0, &X);} -expr(A) ::= BLOB(X). {A = sqlite3Expr(@X, 0, 0, &X);} -expr(A) ::= REGISTER(X). {A = sqlite3RegisterExpr(pParse, &X);} -expr(A) ::= VARIABLE(X). { - Token *pToken = &X; - Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); - sqlite3ExprAssignVarNumber(pParse, pExpr); -} -expr(A) ::= ID(X) LP exprlist(Y) RP(E). { - A = sqlite3ExprFunction(Y, &X); - sqlite3ExprSpan(A,&X,&E); -} -expr(A) ::= ID(X) LP STAR RP(E). { - A = sqlite3ExprFunction(0, &X); - sqlite3ExprSpan(A,&X,&E); -} -term(A) ::= CTIME(OP). {A = sqlite3Expr(@OP,0,0,0);} -term(A) ::= CDATE(OP). {A = sqlite3Expr(@OP,0,0,0);} -term(A) ::= CTIMESTAMP(OP). {A = sqlite3Expr(@OP,0,0,0);} -expr(A) ::= expr(X) AND(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) OR(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) LT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) GT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) LE(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) GE(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) NE(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) EQ(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) BITAND(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) BITOR(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) LSHIFT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) RSHIFT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) PLUS(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) MINUS(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) STAR(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) SLASH(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) REM(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -expr(A) ::= expr(X) CONCAT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} -%type likeop {struct LikeOp} -likeop(A) ::= LIKE. {A.opcode = TK_LIKE; A.not = 0;} -likeop(A) ::= GLOB. {A.opcode = TK_GLOB; A.not = 0;} -likeop(A) ::= NOT LIKE. {A.opcode = TK_LIKE; A.not = 1;} -likeop(A) ::= NOT GLOB. {A.opcode = TK_GLOB; A.not = 1;} -%type escape {Expr*} -escape(X) ::= ESCAPE expr(A). [ESCAPE] {X = A;} -escape(X) ::= . [ESCAPE] {X = 0;} -expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E). [LIKE] { - ExprList *pList = sqlite3ExprListAppend(0, Y, 0); - pList = sqlite3ExprListAppend(pList, X, 0); - if( E ){ - pList = sqlite3ExprListAppend(pList, E, 0); - } - A = sqlite3ExprFunction(pList, 0); - if( A ) A->op = OP.opcode; - if( OP.not ) A = sqlite3Expr(TK_NOT, A, 0, 0); - sqlite3ExprSpan(A, &X->span, &Y->span); -} - -expr(A) ::= expr(X) ISNULL(E). { - A = sqlite3Expr(TK_ISNULL, X, 0, 0); - sqlite3ExprSpan(A,&X->span,&E); -} -expr(A) ::= expr(X) IS NULL(E). { - A = sqlite3Expr(TK_ISNULL, X, 0, 0); - sqlite3ExprSpan(A,&X->span,&E); -} -expr(A) ::= expr(X) NOTNULL(E). { - A = sqlite3Expr(TK_NOTNULL, X, 0, 0); - sqlite3ExprSpan(A,&X->span,&E); -} -expr(A) ::= expr(X) NOT NULL(E). { - A = sqlite3Expr(TK_NOTNULL, X, 0, 0); - sqlite3ExprSpan(A,&X->span,&E); -} -expr(A) ::= expr(X) IS NOT NULL(E). { - A = sqlite3Expr(TK_NOTNULL, X, 0, 0); - sqlite3ExprSpan(A,&X->span,&E); -} -expr(A) ::= NOT(B) expr(X). { - A = sqlite3Expr(@B, X, 0, 0); - sqlite3ExprSpan(A,&B,&X->span); -} -expr(A) ::= BITNOT(B) expr(X). { - A = sqlite3Expr(@B, X, 0, 0); - sqlite3ExprSpan(A,&B,&X->span); -} -expr(A) ::= MINUS(B) expr(X). [UMINUS] { - A = sqlite3Expr(TK_UMINUS, X, 0, 0); - sqlite3ExprSpan(A,&B,&X->span); -} -expr(A) ::= PLUS(B) expr(X). [UPLUS] { - A = sqlite3Expr(TK_UPLUS, X, 0, 0); - sqlite3ExprSpan(A,&B,&X->span); -} -%type between_op {int} -between_op(A) ::= BETWEEN. {A = 0;} -between_op(A) ::= NOT BETWEEN. {A = 1;} -expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { - ExprList *pList = sqlite3ExprListAppend(0, X, 0); - pList = sqlite3ExprListAppend(pList, Y, 0); - A = sqlite3Expr(TK_BETWEEN, W, 0, 0); - if( A ) A->pList = pList; - if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); - sqlite3ExprSpan(A,&W->span,&Y->span); -} -%ifndef SQLITE_OMIT_SUBQUERY - %type in_op {int} - in_op(A) ::= IN. {A = 0;} - in_op(A) ::= NOT IN. {A = 1;} - expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] { - A = sqlite3Expr(TK_IN, X, 0, 0); - if( A ) A->pList = Y; - if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); - sqlite3ExprSpan(A,&X->span,&E); - } - expr(A) ::= LP(B) select(X) RP(E). { - A = sqlite3Expr(TK_SELECT, 0, 0, 0); - if( A ) A->pSelect = X; - sqlite3ExprSpan(A,&B,&E); - } - expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] { - A = sqlite3Expr(TK_IN, X, 0, 0); - if( A ) A->pSelect = Y; - if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); - sqlite3ExprSpan(A,&X->span,&E); - } - expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] { - SrcList *pSrc = sqlite3SrcListAppend(0,&Y,&Z); - A = sqlite3Expr(TK_IN, X, 0, 0); - if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); - if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); - sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y); - } - expr(A) ::= EXISTS(B) LP select(Y) RP(E). { - Expr *p = A = sqlite3Expr(TK_EXISTS, 0, 0, 0); - if( p ){ - p->pSelect = Y; - sqlite3ExprSpan(p,&B,&E); - } - } -%endif // SQLITE_OMIT_SUBQUERY - -/* CASE expressions */ -expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { - A = sqlite3Expr(TK_CASE, X, Z, 0); - if( A ) A->pList = Y; - sqlite3ExprSpan(A, &C, &E); -} -%type case_exprlist {ExprList*} -%destructor case_exprlist {sqlite3ExprListDelete($$);} -case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). { - A = sqlite3ExprListAppend(X, Y, 0); - A = sqlite3ExprListAppend(A, Z, 0); -} -case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). { - A = sqlite3ExprListAppend(0, Y, 0); - A = sqlite3ExprListAppend(A, Z, 0); -} -%type case_else {Expr*} -case_else(A) ::= ELSE expr(X). {A = X;} -case_else(A) ::= . {A = 0;} -%type case_operand {Expr*} -case_operand(A) ::= expr(X). {A = X;} -case_operand(A) ::= . {A = 0;} - -%type exprlist {ExprList*} -%destructor exprlist {sqlite3ExprListDelete($$);} -%type expritem {Expr*} -%destructor expritem {sqlite3ExprDelete($$);} - -exprlist(A) ::= exprlist(X) COMMA expritem(Y). - {A = sqlite3ExprListAppend(X,Y,0);} -exprlist(A) ::= expritem(X). {A = sqlite3ExprListAppend(0,X,0);} -expritem(A) ::= expr(X). {A = X;} -expritem(A) ::= . {A = 0;} - -///////////////////////////// The CREATE INDEX command /////////////////////// -// -cmd ::= CREATE(S) uniqueflag(U) INDEX nm(X) dbnm(D) - ON nm(Y) LP idxlist(Z) RP(E) onconf(R). { - if( U!=OE_None ) U = R; - if( U==OE_Default) U = OE_Abort; - sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(0,&Y,0),Z,U, &S, &E); -} - -%type uniqueflag {int} -uniqueflag(A) ::= UNIQUE. {A = OE_Abort;} -uniqueflag(A) ::= . {A = OE_None;} - -%type idxlist {ExprList*} -%destructor idxlist {sqlite3ExprListDelete($$);} -%type idxlist_opt {ExprList*} -%destructor idxlist_opt {sqlite3ExprListDelete($$);} -%type idxitem {Token} - -idxlist_opt(A) ::= . {A = 0;} -idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;} -idxlist(A) ::= idxlist(X) COMMA idxitem(Y) collate(C) sortorder. { - Expr *p = 0; - if( C.n>0 ){ - p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, C.z, C.n); - } - A = sqlite3ExprListAppend(X, p, &Y); -} -idxlist(A) ::= idxitem(Y) collate(C) sortorder. { - Expr *p = 0; - if( C.n>0 ){ - p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, C.z, C.n); - } - A = sqlite3ExprListAppend(0, p, &Y); -} -idxitem(A) ::= nm(X). {A = X;} - - -///////////////////////////// The DROP INDEX command ///////////////////////// -// -cmd ::= DROP INDEX fullname(X). {sqlite3DropIndex(pParse, X);} - -///////////////////////////// The VACUUM command ///////////////////////////// -// -cmd ::= VACUUM. {sqlite3Vacuum(pParse,0);} -cmd ::= VACUUM nm. {sqlite3Vacuum(pParse,0);} - -///////////////////////////// The PRAGMA command ///////////////////////////// -// -%ifndef SQLITE_OMIT_PRAGMA -cmd ::= PRAGMA nm(X) dbnm(Z) EQ nm(Y). {sqlite3Pragma(pParse,&X,&Z,&Y,0);} -cmd ::= PRAGMA nm(X) dbnm(Z) EQ ON(Y). {sqlite3Pragma(pParse,&X,&Z,&Y,0);} -cmd ::= PRAGMA nm(X) dbnm(Z) EQ plus_num(Y). {sqlite3Pragma(pParse,&X,&Z,&Y,0);} -cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y). { - sqlite3Pragma(pParse,&X,&Z,&Y,1); -} -cmd ::= PRAGMA nm(X) dbnm(Z) LP nm(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);} -cmd ::= PRAGMA nm(X) dbnm(Z). {sqlite3Pragma(pParse,&X,&Z,0,0);} -%endif // SQLITE_OMIT_PRAGMA -plus_num(A) ::= plus_opt number(X). {A = X;} -minus_num(A) ::= MINUS number(X). {A = X;} -number(A) ::= INTEGER(X). {A = X;} -number(A) ::= FLOAT(X). {A = X;} -plus_opt ::= PLUS. -plus_opt ::= . - -//////////////////////////// The CREATE TRIGGER command ///////////////////// - -%ifndef SQLITE_OMIT_TRIGGER - -cmd ::= CREATE trigger_decl(A) BEGIN trigger_cmd_list(S) END(Z). { - Token all; - all.z = A.z; - all.n = (Z.z - A.z) + Z.n; - sqlite3FinishTrigger(pParse, S, &all); -} - -trigger_decl(A) ::= temp(T) TRIGGER nm(B) dbnm(Z) trigger_time(C) - trigger_event(D) - ON fullname(E) foreach_clause(F) when_clause(G). { - sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, F, G, T); - A = (Z.n==0?B:Z); -} - -%type trigger_time {int} -trigger_time(A) ::= BEFORE. { A = TK_BEFORE; } -trigger_time(A) ::= AFTER. { A = TK_AFTER; } -trigger_time(A) ::= INSTEAD OF. { A = TK_INSTEAD;} -trigger_time(A) ::= . { A = TK_BEFORE; } - -%type trigger_event {struct TrigEvent} -%destructor trigger_event {sqlite3IdListDelete($$.b);} -trigger_event(A) ::= DELETE(OP). {A.a = @OP; A.b = 0;} -trigger_event(A) ::= INSERT(OP). {A.a = @OP; A.b = 0;} -trigger_event(A) ::= UPDATE(OP). {A.a = @OP; A.b = 0;} -trigger_event(A) ::= UPDATE OF inscollist(X). {A.a = TK_UPDATE; A.b = X;} - -%type foreach_clause {int} -foreach_clause(A) ::= . { A = TK_ROW; } -foreach_clause(A) ::= FOR EACH ROW. { A = TK_ROW; } -foreach_clause(A) ::= FOR EACH STATEMENT. { A = TK_STATEMENT; } - -%type when_clause {Expr*} -when_clause(A) ::= . { A = 0; } -when_clause(A) ::= WHEN expr(X). { A = X; } - -%type trigger_cmd_list {TriggerStep*} -%destructor trigger_cmd_list {sqlite3DeleteTriggerStep($$);} -trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). { - X->pNext = Y; - A = X; -} -trigger_cmd_list(A) ::= . { A = 0; } - -%type trigger_cmd {TriggerStep*} -%destructor trigger_cmd {sqlite3DeleteTriggerStep($$);} -// UPDATE -trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z). - { A = sqlite3TriggerUpdateStep(&X, Y, Z, R); } - -// INSERT -trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) - VALUES LP itemlist(Y) RP. - {A = sqlite3TriggerInsertStep(&X, F, Y, 0, R);} - -trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) select(S). - {A = sqlite3TriggerInsertStep(&X, F, 0, S, R);} - -// DELETE -trigger_cmd(A) ::= DELETE FROM nm(X) where_opt(Y). - {A = sqlite3TriggerDeleteStep(&X, Y);} - -// SELECT -trigger_cmd(A) ::= select(X). {A = sqlite3TriggerSelectStep(X); } - -// The special RAISE expression that may occur in trigger programs -expr(A) ::= RAISE(X) LP IGNORE RP(Y). { - A = sqlite3Expr(TK_RAISE, 0, 0, 0); - A->iColumn = OE_Ignore; - sqlite3ExprSpan(A, &X, &Y); -} -expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y). { - A = sqlite3Expr(TK_RAISE, 0, 0, &Z); - A->iColumn = T; - sqlite3ExprSpan(A, &X, &Y); -} -%endif // !SQLITE_OMIT_TRIGGER - -%type raisetype {int} -raisetype(A) ::= ROLLBACK. {A = OE_Rollback;} -raisetype(A) ::= ABORT. {A = OE_Abort;} -raisetype(A) ::= FAIL. {A = OE_Fail;} - - -//////////////////////// DROP TRIGGER statement ////////////////////////////// -%ifndef SQLITE_OMIT_TRIGGER -cmd ::= DROP TRIGGER fullname(X). { - sqlite3DropTrigger(pParse,X); -} -%endif // !SQLITE_OMIT_TRIGGER - -//////////////////////// ATTACH DATABASE file AS name ///////////////////////// -cmd ::= ATTACH database_kw_opt ids(F) AS nm(D) key_opt(K). { - sqlite3Attach(pParse, &F, &D, K.type, &K.key); -} -%type key_opt {struct AttachKey} -key_opt(A) ::= . { A.type = 0; } -key_opt(A) ::= KEY ids(X). { A.type=1; A.key = X; } -key_opt(A) ::= KEY BLOB(X). { A.type=2; A.key = X; } - -database_kw_opt ::= DATABASE. -database_kw_opt ::= . - -//////////////////////// DETACH DATABASE name ///////////////////////////////// -cmd ::= DETACH database_kw_opt nm(D). { - sqlite3Detach(pParse, &D); -} - -////////////////////////// REINDEX collation ////////////////////////////////// -%ifndef SQLITE_OMIT_REINDEX -cmd ::= REINDEX. {sqlite3Reindex(pParse, 0, 0);} -cmd ::= REINDEX nm(X) dbnm(Y). {sqlite3Reindex(pParse, &X, &Y);} -%endif - -//////////////////////// ALTER TABLE table ... //////////////////////////////// -%ifndef SQLITE_OMIT_ALTERTABLE -cmd ::= ALTER TABLE fullname(X) RENAME TO nm(Z). { - sqlite3AlterRenameTable(pParse,X,&Z); -} -%endif diff --git a/sqlite/src/pragma.c b/sqlite/src/pragma.c deleted file mode 100644 index 51cdf98..0000000 --- a/sqlite/src/pragma.c +++ /dev/null @@ -1,912 +0,0 @@ -/* -** 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.89 2005/02/09 03:20:37 danielk1977 Exp $ -*/ -#include "sqliteInt.h" -#include "os.h" -#include - -/* Ignore this whole file if pragmas are disabled -*/ -#ifndef SQLITE_OMIT_PRAGMA - -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) -# include "pager.h" -# include "btree.h" -#endif - -/* -** Interpret the given string as a 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='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; - } -} - -/* -** 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; -} - -/* -** If the TEMP database is open, close it and mark the database schema -** as needing reloading. This must be done when using the TEMP_STORE -** or DEFAULT_TEMP_STORE pragmas. -*/ -static int changeTempStorage(Parse *pParse, const char *zStorageType){ - int ts = getTempStore(zStorageType); - sqlite3 *db = pParse->db; - if( db->temp_store==ts ) return SQLITE_OK; - if( invalidateTempStorage( pParse ) != SQLITE_OK ){ - return SQLITE_ERROR; - } - db->temp_store = ts; - return SQLITE_OK; -} -#endif - -/* -** Generate code to return a single integer value. -*/ -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); -} - -/* -** 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; izName)==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; -} - -/* -** 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 , or NULL */ - int minusFlag /* True if a '-' sign preceded */ -){ - char *zLeft = 0; /* Nul-terminated UTF-8 string */ - char *zRight = 0; /* Nul-terminated UTF-8 string , or NULL */ - const char *zDb = 0; /* The database name */ - Token *pId; /* Pointer to token */ - int iDb; /* Database index for */ - 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 */ - - if( flagPragma(pParse, zLeft, zRight) ){ - /* The flagPragma() subroutine also generates any necessary code - ** there is nothing more to do here */ - }else - -#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS - /* - ** PRAGMA table_info(
) - ** - ** 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; inCol; 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; inColumn; 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; inDb; i++){ - if( db->aDb[i].pBt==0 ) continue; - assert( db->aDb[i].zName!=0 ); - sqlite3VdbeAddOp(v, OP_Integer, i, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, - sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); - sqlite3VdbeAddOp(v, OP_Callback, 3, 0); - } - }else - - if( sqlite3StrICmp(zLeft, "collation_list")==0 ){ - int i = 0; - HashElem *p; - sqlite3VdbeSetNumCols(v, 2); - sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC); - sqlite3VdbeSetColName(v, 1, "name", P3_STATIC); - for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ - CollSeq *pColl = (CollSeq *)sqliteHashData(p); - sqlite3VdbeAddOp(v, OP_Integer, i++, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pColl->zName, 0); - sqlite3VdbeAddOp(v, OP_Callback, 2, 0); - } - }else -#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ - -#ifndef SQLITE_OMIT_FOREIGN_KEY - if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ - FKey *pFK; - Table *pTab; - 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; jnCol; 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; inDb; i++){ - HashElem *x; - int cnt = 0; - - 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_Recno, 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 = - ** - ** PRAGMA [database.]user_version - ** PRAGMA [database.]user_version = - ** - ** The pragma's schema_version and user_version are used to set or get - ** the value of the schema-version and user-version, respectively. Both - ** the schema-version and the user-version are 32-bit signed integers - ** stored in the database header. - ** - ** The schema-cookie is usually only manipulated internally by SQLite. It - ** is incremented by SQLite whenever the database schema is modified (by - ** creating or dropping a table or index). The schema version is used by - ** SQLite each time a query is executed to ensure that the internal cache - ** of the schema used when compiling the SQL query matches the schema of - ** the database against which the compiled query is actually executed. - ** Subverting this mechanism by using "PRAGMA schema_version" to modify - ** the schema-version is potentially dangerous and may lead to program - ** crashes or database corruption. Use with caution! - ** - ** The user-version is not used internally by SQLite. It may be used by - ** applications for any purpose. - */ - if( sqlite3StrICmp(zLeft, "schema_version")==0 || - sqlite3StrICmp(zLeft, "user_version")==0 ){ - - int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */ - if( zLeft[0]=='s' || zLeft[0]=='S' ){ - iCookie = 0; - }else{ - iCookie = 5; - } - - if( zRight ){ - /* Write the specified cookie value */ - static const VdbeOpList setCookie[] = { - { OP_Transaction, 0, 1, 0}, /* 0 */ - { OP_Integer, 0, 0, 0}, /* 1 */ - { OP_SetCookie, 0, 0, 0}, /* 2 */ - }; - int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie); - sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP1(v, addr+1, atoi(zRight)); - sqlite3VdbeChangeP1(v, addr+2, iDb); - sqlite3VdbeChangeP2(v, addr+2, iCookie); - }else{ - /* Read the specified cookie value */ - static const VdbeOpList readCookie[] = { - { OP_ReadCookie, 0, 0, 0}, /* 0 */ - { OP_Callback, 1, 0, 0} - }; - int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); - sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP2(v, addr, iCookie); - sqlite3VdbeSetNumCols(v, 1); - } - } -#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ - -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - /* - ** 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; inDb; 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 - - {} - - if( v ){ - /* Code an OP_Expire at the end of each PRAGMA program to cause - ** the VDBE implementing the pragma to expire. Most (all?) pragmas - ** are only valid for a single execution. - */ - sqlite3VdbeAddOp(v, OP_Expire, 1, 0); - } -pragma_out: - sqliteFree(zLeft); - sqliteFree(zRight); -} - -#endif /* SQLITE_OMIT_PRAGMA */ diff --git a/sqlite/src/printf.c b/sqlite/src/printf.c deleted file mode 100644 index 6e70077..0000000 --- a/sqlite/src/printf.c +++ /dev/null @@ -1,831 +0,0 @@ -/* -** 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; idxflags & 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 && precisioncharset]; - 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+precision0 || flag_alternateform); - if( prefix ) *(bufpt++) = prefix; /* Sign */ - if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */ - else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd); - if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */ - for(exp++; exp<0 && precision>0; precision--, exp++){ - *(bufpt++) = '0'; - } - 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=0 && precisionetBUFSIZE ){ - bufpt = zExtra = sqliteMalloc( n ); - if( bufpt==0 ) return -1; - }else{ - bufpt = buf; - } - j = 0; - if( needQuote ) bufpt[j++] = '\''; - for(i=0; (c=arg[i])!=0; i++){ - bufpt[j++] = c; - if( c=='\'' ) bufpt[j++] = c; - } - if( needQuote ) bufpt[j++] = '\''; - bufpt[j] = 0; - length = j; - if( precision>=0 && precisionz ){ - (*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 && knSrc ); - 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/sqlite/src/select.c b/sqlite/src/select.c deleted file mode 100644 index b792f9d..0000000 --- a/sqlite/src/select.c +++ /dev/null @@ -1,2877 +0,0 @@ -/* -** 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.241 2005/02/12 08:59:57 danielk1977 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; jn==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; inCol; 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; inSrc-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; jnCol; 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; jnId; 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; inExpr; i++){ - sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr); - } - sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0); - sqlite3VdbeAddOp(v, OP_SortPut, 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; inExpr; - for(i=0; inExpr; 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_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutStrKey, 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_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutStrKey, 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_NewRecno, iParm, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, 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_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutStrKey, (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; ia[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_NewRecno, iParm, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0); - break; - } -#ifndef SQLITE_OMIT_SUBQUERY - case SRT_Set: { - assert( nColumn==1 ); - sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); - 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_String8, 0, 0); - sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0); - break; - } - case SRT_Exists: - case SRT_Mem: { - assert( nColumn==1 ); - sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); - sqlite3VdbeAddOp(v, OP_Goto, 0, end1); - break; - } -#endif - case SRT_Callback: - case SRT_Subroutine: { - int i; - sqlite3VdbeAddOp(v, OP_Integer, p->pEList->nExpr, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - for(i=0; ipSrcList==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;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); - if( jnSrc ){ - pTab = pTabList->a[j].pTab; - }else{ - pNC = pNC->pNext; - } - } - assert( pTab ); - if( iCol<0 ) iCol = pTab->iPKey; - assert( iCol==-1 || (iCol>=0 && iColnCol) ); - if( iCol<0 ){ - 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; inExpr; 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; inExpr; 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; jnSrc && pTabList->a[j].iCursor!=p->iTable; j++){} - assert( jnSrc ); - pTab = pTabList->a[j].pTab; - if( iCol<0 ) iCol = pTab->iPKey; - assert( iCol==-1 || (iCol>=0 && iColnCol) ); - 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->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; inCol; 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 " phrase, use as the name */ - zName = sqliteStrDup(zName); - }else if( p->op==TK_DOT - && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){ - /* 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); - - /* Make sure the column name is unique. If the name is not unique, - ** append a integer to the name so that it becomes unique. - */ - zBasename = zName; - for(j=cnt=0; jzName = zName; - - /* Get the typename, type affinity, and collating sequence for the - ** column. - */ - sNC.pSrcList = pSelect->pSrc; - zType = sqliteStrDup(columnType(&sNC, p)); - pCol->zType = zType; - pCol->affinity = 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 ) 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; inSrc; 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); - } - 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 */ - pFrom->pTab = pTab = - sqlite3LocateTable(pParse,pFrom->zName,pFrom->zDatabase); - if( pTab==0 ){ - return 1; - } -#ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ - /* We reach here if the named table is a really a view */ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - 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; knExpr; 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( knExpr ){ - /* - ** 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; - for(k=0; knExpr; 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; inSrc; 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; jnCol; 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 && 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; - } - 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; -} - -/* -** This routine recursively unlinks the Select.pSrc.a[].pTab pointers -** in a select structure. It just sets the pointers to NULL. This -** routine is recursive in the sense that if the Select.pSrc.a[].pSelect -** pointer is not NULL, this routine is called recursively on that pointer. -** -** This routine is called on the Select structure that defines a -** VIEW in order to undo any bindings to tables. This is necessary -** because those tables might be DROPed by a subsequent SQL command. -** If the bindings are not removed, then the Select.pSrc->a[].pTab field -** will be left pointing to a deallocated Table structure after the -** DROP and a coredump will occur the next time the VIEW is used. -*/ -#if 0 -void sqlite3SelectUnbind(Select *p){ - int i; - SrcList *pSrc = p->pSrc; - struct SrcList_item *pItem; - Table *pTab; - if( p==0 ) return; - for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ - if( (pTab = pItem->pTab)!=0 ){ - if( pTab->isTransient ){ - sqlite3DeleteTable(0, pTab); - } - pItem->pTab = 0; - if( pItem->pSelect ){ - sqlite3SelectUnbind(pItem->pSelect); - } - } - } -} -#endif - -#ifndef SQLITE_OMIT_COMPOUND_SELECT -/* -** This routine associates entries in an ORDER BY expression list with -** columns in a result. For each ORDER BY expression, the opcode of -** 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; inExpr; 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; inExpr; 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 && jnExpr; 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). -** -** Make the new table a KeyAsData table if keyAsData is true. -** -** The value returned is the address of the OP_OpenTemp instruction. -*/ -static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){ - 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; iaColl[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); - if( keyAsData ){ - sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1); - } - 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; - } - sqlite3VdbeAddOp(v, OP_KeyAsData, unionTab, 1); - } - assert( nAddrpEList ); - } - - /* 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; - } - sqlite3VdbeAddOp(v, OP_KeyAsData, tab1, 1); - assert( nAddrpEList ); - - /* 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; - } - sqlite3VdbeAddOp(v, OP_KeyAsData, tab2, 1); - assert( nAddrpPrior = 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_FullKey, 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; iaColl[i] = multiSelectCollSeq(pParse, p, i); - if( !pKeyInfo->aColl[i] ){ - pKeyInfo->aColl[i] = pParse->db->pDfltColl; - } - } - - for(i=0; pOpenTemp && inId; 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; ipOrderBy->nExpr; i++, pOrderByTerm++){ - Expr *pExpr = pOrderByTerm->pExpr; - char *zName = pOrderByTerm->zName; - assert( pExpr->op==TK_COLUMN && pExpr->iColumnpColl ); */ - 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->iColumnnExpr ); - 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; inExpr; i++){ - substExpr(pList->a[i].pExpr, iTable, pEList); - } -} -static void substSelect(Select *p, int iTable, ExprList *pEList){ - if( !p ) return; - substExprList(p->pEList, iTable, pEList); - substExprList(p->pGroupBy, iTable, pEList); - substExprList(p->pOrderBy, iTable, pEList); - substExpr(p->pHaving, iTable, pEList); - substExpr(p->pWhere, iTable, pEList); -} -#endif /* !defined(SQLITE_OMIT_VIEW) */ - -#ifndef SQLITE_OMIT_VIEW -/* -** This routine attempts to flatten subqueries in order to speed -** execution. It returns 1 if it makes changes and 0 if no flattening -** 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 && iFromnSrc ); - 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; - Table *pTab = pSubitem->pTab; - - if( pTab && pTab->isTransient ){ - sqlite3DeleteTable(0, pSubitem->pTab); - } - sqliteFree(pSubitem->zDatabase); - sqliteFree(pSubitem->zName); - sqliteFree(pSubitem->zAlias); - if( nSubSrc>1 ){ - int extra = nSubSrc - 1; - for(i=1; ipSrc = pSrc; - for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){ - pSrc->a[i] = pSrc->a[i-extra]; - } - } - for(i=0; ia[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; inExpr; 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_String, 0, 0); - sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0); - seekOp = OP_MoveGt; - } - sqlite3VdbeAddOp(v, seekOp, iIdx, 0); - sqlite3VdbeAddOp(v, OP_IdxRecno, iIdx, 0); - sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); - sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); - } - eList.nExpr = 1; - 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; inExpr; 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; inExpr; i++){ - Expr *pX = pEList->a[i].pExpr; - if( sqlite3ExprResolveNames(&sNC, pX) ){ - return SQLITE_ERROR; - } - } - - /* If there are no aggregate functions in the result-set, and no GROUP BY - ** expression, do not allow aggregates in any of the other expressions. - */ - assert( !p->isAgg ); - if( p->pGroupBy || sNC.hasAgg ){ - p->isAgg = 1; - }else{ - sNC.allowAgg = 0; - } - - /* If a HAVING clause is present, then there must be a GROUP BY clause. - */ - if( p->pHaving && !p->pGroupBy ){ - sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); - return SQLITE_ERROR; - } - - /* Add the expression list to the name-context before parsing the - ** other expressions in the SELECT statement. This is so that - ** expressions in the WHERE clause (etc.) can refer to expressions by - ** aliases in the result set. - ** - ** Minor point: If this is the case, then the expression will be - ** re-evaluated for each reference to it. - */ - sNC.pEList = p->pEList; - if( sqlite3ExprResolveNames(&sNC, p->pWhere) || - sqlite3ExprResolveNames(&sNC, p->pHaving) || - processOrderGroupBy(&sNC, p->pOrderBy, "ORDER") || - processOrderGroupBy(&sNC, p->pGroupBy, "GROUP") - ){ - return SQLITE_ERROR; - } - - return SQLITE_OK; -} - -/* -** An instance of the following struct is used by sqlite3Select() -** to save aggregate related information from the Parse object -** at the start of each call and to restore it at the end. See -** saveAggregateInfo() and restoreAggregateInfo(). -*/ -struct AggregateInfo { - int nAgg; - AggExpr *aAgg; -}; -typedef struct AggregateInfo AggregateInfo; - -/* -** Copy aggregate related information from the Parse structure -** into the AggregateInfo structure. Zero the aggregate related -** values in the Parse struct. -*/ -static void saveAggregateInfo(Parse *pParse, AggregateInfo *pInfo){ - pInfo->aAgg = pParse->aAgg; - pInfo->nAgg = pParse->nAgg; - pParse->aAgg = 0; - pParse->nAgg = 0; -} - -/* -** Copy aggregate related information from the AggregateInfo struct -** back into the Parse structure. The aggregate related information -** currently stored in the Parse structure is deleted. -*/ -static void restoreAggregateInfo(Parse *pParse, AggregateInfo *pInfo){ - sqliteFree(pParse->aAgg); - pParse->aAgg = pInfo->aAgg; - pParse->nAgg = pInfo->nAgg; -} - -/* -** Generate code for the given SELECT statement. -** -** 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; inSrc; 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; inExpr; 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; inExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(&sNC, pEList->a[i].pExpr) ){ - goto select_end; - } - } - if( pGroupBy ){ - for(i=0; inExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(&sNC, pGroupBy->a[i].pExpr) ){ - goto select_end; - } - } - } - if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){ - goto select_end; - } - if( pOrderBy ){ - for(i=0; inExpr; 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; inAgg; i++){ - FuncDef *pFunc; - if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){ - sqlite3VdbeOp3(v, OP_AggInit, 0, 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; inExpr; 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_String8 : 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, 0); - }else{ - distinct = -1; - } - - /* Begin the database scan - */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, - pGroupBy ? 0 : &pOrderBy, p->pFetch); - if( pWInfo==0 ) goto select_end; - - /* Use the standard inner loop if we are not dealing with - ** 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; inExpr; 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; inAgg; i++, pAgg++){ - if( pAgg->isAgg ) continue; - sqlite3ExprCode(pParse, pAgg->pExpr); - sqlite3VdbeAddOp(v, OP_AggSet, 0, i); - } - pParse->fillAgg = 0; - if( lbl1<0 ){ - sqlite3VdbeResolveLabel(v, lbl1); - } - for(i=0, pAgg=pParse->aAgg; inAgg; i++, pAgg++){ - 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 && jpList->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_POINTER); - } - } - - /* 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/sqlite/src/shell.c b/sqlite/src/shell.c deleted file mode 100644 index e086757..0000000 --- a/sqlite/src/shell.c +++ /dev/null @@ -1,1801 +0,0 @@ -/* -** 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 the "sqlite" command line -** utility for accessing SQLite databases. -** -** $Id: shell.c,v 1.121 2005/02/03 00:42:35 drh Exp $ -*/ -#include -#include -#include -#include -#include "sqlite3.h" -#include - -#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) -# include -# include -# include -# include -#endif - -#ifdef __MACOS__ -# include -# include -# include -# include -# include -# include -#endif - -#if defined(HAVE_READLINE) && HAVE_READLINE==1 -# include -# include -#else -# define readline(p) local_getline(p,stdin) -# define add_history(X) -# define read_history(X) -# define write_history(X) -# define stifle_history(X) -#endif - -/* Make sure isatty() has a prototype. -*/ -extern int isatty(); - -/* -** The following is the open SQLite database. We make a pointer -** to this database a static variable so that it can be accessed -** by the SIGINT handler to interrupt database processing. -*/ -static sqlite3 *db = 0; - -/* -** True if an interrupt (Control-C) has been received. -*/ -static int seenInterrupt = 0; - -/* -** This is the name of our program. It is set in main(), used -** in a number of other places, mostly for error messages. -*/ -static char *Argv0; - -/* -** Prompt strings. Initialized in main. Settable with -** .prompt main continue -*/ -static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ -static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ - - -/* -** Determines if a string is a number of not. -*/ -static int isNumber(const unsigned char *z, int *realnum){ - if( *z=='-' || *z=='+' ) z++; - if( !isdigit(*z) ){ - return 0; - } - z++; - if( realnum ) *realnum = 0; - while( isdigit(*z) ){ z++; } - if( *z=='.' ){ - z++; - if( !isdigit(*z) ) return 0; - while( isdigit(*z) ){ z++; } - if( realnum ) *realnum = 1; - } - if( *z=='e' || *z=='E' ){ - z++; - if( *z=='+' || *z=='-' ) z++; - if( !isdigit(*z) ) return 0; - while( isdigit(*z) ){ z++; } - if( realnum ) *realnum = 1; - } - return *z==0; -} - -/* -** A global char* and an SQL function to access its current value -** from within an SQL statement. This program used to use the -** sqlite_exec_printf() API to substitue a string into an SQL statement. -** The correct way to do this with sqlite3 is to use the bind API, but -** since the shell is built around the callback paradigm it would be a lot -** of work. Instead just use this hack, which is quite harmless. -*/ -static const char *zShellStatic = 0; -static void shellstaticFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - assert( 0==argc ); - assert( zShellStatic ); - sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC); -} - - -/* -** This routine reads a line of text from FILE in, stores -** the text in memory obtained from malloc() and returns a pointer -** to the text. NULL is returned at end of file, or if malloc() -** fails. -** -** The interface is like "readline" but no command-line editing -** is done. -*/ -static char *local_getline(char *zPrompt, FILE *in){ - char *zLine; - int nLine; - int n; - int eol; - - if( zPrompt && *zPrompt ){ - printf("%s",zPrompt); - fflush(stdout); - } - nLine = 100; - zLine = malloc( nLine ); - if( zLine==0 ) return 0; - n = 0; - eol = 0; - while( !eol ){ - if( n+100>nLine ){ - nLine = nLine*2 + 100; - zLine = realloc(zLine, nLine); - if( zLine==0 ) return 0; - } - if( fgets(&zLine[n], nLine - n, in)==0 ){ - if( n==0 ){ - free(zLine); - return 0; - } - zLine[n] = 0; - eol = 1; - break; - } - while( zLine[n] ){ n++; } - if( n>0 && zLine[n-1]=='\n' ){ - n--; - zLine[n] = 0; - eol = 1; - } - } - zLine = realloc( zLine, n+1 ); - return zLine; -} - -/* -** Retrieve a single line of input text. "isatty" is true if text -** is coming from a terminal. In that case, we issue a prompt and -** attempt to use "readline" for command-line editing. If "isatty" -** is false, use "local_getline" instead of "readline" and issue no prompt. -** -** zPrior is a string of prior text retrieved. If not the empty -** string, then issue a continuation prompt. -*/ -static char *one_input_line(const char *zPrior, FILE *in){ - char *zPrompt; - char *zResult; - if( in!=0 ){ - return local_getline(0, in); - } - if( zPrior && zPrior[0] ){ - zPrompt = continuePrompt; - }else{ - zPrompt = mainPrompt; - } - zResult = readline(zPrompt); -#if defined(HAVE_READLINE) && HAVE_READLINE==1 - if( zResult ) add_history(zResult); -#endif - return zResult; -} - -struct previous_mode_data { - int valid; /* Is there legit data in here? */ - int mode; - int showHeader; - int colWidth[100]; -}; -/* -** An pointer to an instance of this structure is passed from -** the main program to the callback. This is used to communicate -** state and mode information. -*/ -struct callback_data { - sqlite3 *db; /* The database */ - int echoOn; /* True to echo input commands */ - int cnt; /* Number of records displayed so far */ - FILE *out; /* Write results here */ - int mode; /* An output mode setting */ - int showHeader; /* True to show column names in List or Column mode */ - char *zDestTable; /* Name of destination table when MODE_Insert */ - char separator[20]; /* Separator character for MODE_List */ - int colWidth[100]; /* Requested width of each column when in column mode*/ - int actualWidth[100]; /* Actual width of each column */ - char nullvalue[20]; /* The text to print when a NULL comes back from - ** the database */ - struct previous_mode_data explainPrev; - /* Holds the mode information just before - ** .explain ON */ - char outfile[FILENAME_MAX]; /* Filename for *out */ - const char *zDbFilename; /* name of the database file */ - char *zKey; /* Encryption key */ -}; - -/* -** These are the allowed modes. -*/ -#define MODE_Line 0 /* One column per line. Blank line between records */ -#define MODE_Column 1 /* One record per line in neat columns */ -#define MODE_List 2 /* One record per line with a separator */ -#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ -#define MODE_Html 4 /* Generate an XHTML table */ -#define MODE_Insert 5 /* Generate SQL "insert" statements */ -#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ -#define MODE_Csv 7 /* Quote strings, numbers are plain */ -#define MODE_NUM_OF 8 /* The number of modes (not a mode itself) */ - -char *modeDescr[MODE_NUM_OF] = { - "line", - "column", - "list", - "semi", - "html", - "insert", - "tcl", - "csv", -}; - -/* -** Number of elements in an array -*/ -#define ArraySize(X) (sizeof(X)/sizeof(X[0])) - -/* -** Output the given string as a quoted string using SQL quoting conventions. -*/ -static void output_quoted_string(FILE *out, const char *z){ - int i; - int nSingle = 0; - for(i=0; z[i]; i++){ - if( z[i]=='\'' ) nSingle++; - } - if( nSingle==0 ){ - fprintf(out,"'%s'",z); - }else{ - fprintf(out,"'"); - while( *z ){ - for(i=0; z[i] && z[i]!='\''; i++){} - if( i==0 ){ - fprintf(out,"''"); - z++; - }else if( z[i]=='\'' ){ - fprintf(out,"%.*s''",i,z); - z += i+1; - }else{ - fprintf(out,"%s",z); - break; - } - } - fprintf(out,"'"); - } -} - -/* -** Output the given string as a quoted according to C or TCL quoting rules. -*/ -static void output_c_string(FILE *out, const char *z){ - unsigned int c; - fputc('"', out); - while( (c = *(z++))!=0 ){ - if( c=='\\' ){ - fputc(c, out); - fputc(c, out); - }else if( c=='\t' ){ - fputc('\\', out); - fputc('t', out); - }else if( c=='\n' ){ - fputc('\\', out); - fputc('n', out); - }else if( c=='\r' ){ - fputc('\\', out); - fputc('r', out); - }else if( !isprint(c) ){ - fprintf(out, "\\%03o", c); - }else{ - fputc(c, out); - } - } - fputc('"', out); -} - -/* -** Output the given string with characters that are special to -** HTML escaped. -*/ -static void output_html_string(FILE *out, const char *z){ - int i; - while( *z ){ - for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){} - if( i>0 ){ - fprintf(out,"%.*s",i,z); - } - if( z[i]=='<' ){ - fprintf(out,"<"); - }else if( z[i]=='&' ){ - fprintf(out,"&"); - }else{ - break; - } - z += i + 1; - } -} - -/* -** Output a single term of CSV. Actually, p->separator is used for -** the separator, which may or may not be a comma. p->nullvalue is -** the null value. Strings are quoted using ANSI-C rules. Numbers -** appear outside of quotes. -*/ -static void output_csv(struct callback_data *p, const char *z, int bSep){ - if( z==0 ){ - fprintf(p->out,"%s",p->nullvalue); - }else if( isNumber(z, 0) ){ - fprintf(p->out,"%s",z); - }else{ - output_c_string(p->out, z); - } - if( bSep ){ - fprintf(p->out, p->separator); - } -} - -#ifdef SIGINT -/* -** This routine runs when the user presses Ctrl-C -*/ -static void interrupt_handler(int NotUsed){ - seenInterrupt = 1; - if( db ) sqlite3_interrupt(db); -} -#endif - -/* -** This is the callback routine that the SQLite library -** invokes for each row of a query result. -*/ -static int callback(void *pArg, int nArg, char **azArg, char **azCol){ - int i; - struct callback_data *p = (struct callback_data*)pArg; - switch( p->mode ){ - case MODE_Line: { - int w = 5; - if( azArg==0 ) break; - for(i=0; iw ) w = len; - } - if( p->cnt++>0 ) fprintf(p->out,"\n"); - for(i=0; iout,"%*s = %s\n", w, azCol[i], - azArg[i] ? azArg[i] : p->nullvalue); - } - break; - } - case MODE_Column: { - if( p->cnt++==0 ){ - for(i=0; icolWidth) ){ - w = p->colWidth[i]; - }else{ - w = 0; - } - if( w<=0 ){ - w = strlen(azCol[i] ? azCol[i] : ""); - if( w<10 ) w = 10; - n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue); - if( wactualWidth) ){ - p->actualWidth[i] = w; - } - if( p->showHeader ){ - fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " "); - } - } - if( p->showHeader ){ - for(i=0; iactualWidth) ){ - w = p->actualWidth[i]; - }else{ - w = 10; - } - fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------" - "----------------------------------------------------------", - i==nArg-1 ? "\n": " "); - } - } - } - if( azArg==0 ) break; - for(i=0; iactualWidth) ){ - w = p->actualWidth[i]; - }else{ - w = 10; - } - fprintf(p->out,"%-*.*s%s",w,w, - azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); - } - break; - } - case MODE_Semi: - case MODE_List: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator); - } - } - if( azArg==0 ) break; - for(i=0; inullvalue; - fprintf(p->out, "%s", z); - if( iout, "%s", p->separator); - }else if( p->mode==MODE_Semi ){ - fprintf(p->out, ";\n"); - }else{ - fprintf(p->out, "\n"); - } - } - break; - } - case MODE_Html: { - if( p->cnt++==0 && p->showHeader ){ - fprintf(p->out,""); - for(i=0; iout,"",azCol[i]); - } - fprintf(p->out,"\n"); - } - if( azArg==0 ) break; - fprintf(p->out,""); - for(i=0; iout,"\n"); - } - fprintf(p->out,"\n"); - break; - } - case MODE_Tcl: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout,azCol[i]); - fprintf(p->out, "%s", p->separator); - } - fprintf(p->out,"\n"); - } - if( azArg==0 ) break; - for(i=0; iout, azArg[i] ? azArg[i] : p->nullvalue); - fprintf(p->out, "%s", p->separator); - } - fprintf(p->out,"\n"); - break; - } - case MODE_Csv: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout,"\n"); - } - if( azArg==0 ) break; - for(i=0; iout,"\n"); - break; - } - case MODE_Insert: { - if( azArg==0 ) break; - fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable); - for(i=0; i0 ? ",": ""; - if( azArg[i]==0 ){ - fprintf(p->out,"%sNULL",zSep); - }else if( isNumber(azArg[i], 0) ){ - fprintf(p->out,"%s%s",zSep, azArg[i]); - }else{ - if( zSep[0] ) fprintf(p->out,"%s",zSep); - output_quoted_string(p->out, azArg[i]); - } - } - fprintf(p->out,");\n"); - break; - } - } - return 0; -} - -/* -** Set the destination table field of the callback_data structure to -** the name of the table given. Escape any quote characters in the -** table name. -*/ -static void set_table_name(struct callback_data *p, const char *zName){ - int i, n; - int needQuote; - char *z; - - if( p->zDestTable ){ - free(p->zDestTable); - p->zDestTable = 0; - } - if( zName==0 ) return; - needQuote = !isalpha((unsigned char)*zName) && *zName!='_'; - for(i=n=0; zName[i]; i++, n++){ - if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){ - needQuote = 1; - if( zName[i]=='\'' ) n++; - } - } - if( needQuote ) n += 2; - z = p->zDestTable = malloc( n+1 ); - if( z==0 ){ - fprintf(stderr,"Out of memory!\n"); - exit(1); - } - n = 0; - if( needQuote ) z[n++] = '\''; - for(i=0; zName[i]; i++){ - z[n++] = zName[i]; - if( zName[i]=='\'' ) z[n++] = '\''; - } - if( needQuote ) z[n++] = '\''; - z[n] = 0; -} - -/* zIn is either a pointer to a NULL-terminated string in memory obtained -** from malloc(), or a NULL pointer. The string pointed to by zAppend is -** added to zIn, and the result returned in memory obtained from malloc(). -** zIn, if it was not NULL, is freed. -** -** If the third argument, quote, is not '\0', then it is used as a -** quote character for zAppend. -*/ -static char * appendText(char *zIn, char const *zAppend, char quote){ - int len; - int i; - int nAppend = strlen(zAppend); - int nIn = (zIn?strlen(zIn):0); - - len = nAppend+nIn+1; - if( quote ){ - len += 2; - for(i=0; iout, "%s;\n", zSql); - }else{ - fprintf(p->out, "DELETE FROM sqlite_sequence;\n"); - } - - if( strcmp(zType, "table")==0 ){ - sqlite3_stmt *pTableInfo = 0; - char *zSelect = 0; - char *zTableInfo = 0; - char *zTmp = 0; - - zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0); - zTableInfo = appendText(zTableInfo, zTable, '"'); - zTableInfo = appendText(zTableInfo, ");", 0); - - rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0); - if( zTableInfo ) free(zTableInfo); - if( rc!=SQLITE_OK || !pTableInfo ){ - return 1; - } - - zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0); - zTmp = appendText(zTmp, zTable, '"'); - if( zTmp ){ - zSelect = appendText(zSelect, zTmp, '\''); - } - zSelect = appendText(zSelect, " || ' VALUES(' || ", 0); - rc = sqlite3_step(pTableInfo); - while( rc==SQLITE_ROW ){ - zSelect = appendText(zSelect, "quote(", 0); - zSelect = appendText(zSelect, sqlite3_column_text(pTableInfo, 1), '"'); - rc = sqlite3_step(pTableInfo); - if( rc==SQLITE_ROW ){ - zSelect = appendText(zSelect, ") || ', ' || ", 0); - }else{ - zSelect = appendText(zSelect, ") ", 0); - } - } - rc = sqlite3_finalize(pTableInfo); - if( rc!=SQLITE_OK ){ - if( zSelect ) free(zSelect); - return 1; - } - zSelect = appendText(zSelect, "|| ')' FROM ", 0); - zSelect = appendText(zSelect, zTable, '"'); - - rc = run_table_dump_query(p->out, p->db, zSelect); - if( rc==SQLITE_CORRUPT ){ - zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0); - rc = run_table_dump_query(p->out, p->db, zSelect); - } - if( zSelect ) free(zSelect); - if( rc!=SQLITE_OK ){ - return 1; - } - } - return 0; -} - -/* -** Run zQuery. Update dump_callback() as the callback routine. -** If we get a SQLITE_CORRUPT error, rerun the query after appending -** "ORDER BY rowid DESC" to the end. -*/ -static int run_schema_dump_query( - struct callback_data *p, - const char *zQuery, - char **pzErrMsg -){ - int rc; - rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg); - if( rc==SQLITE_CORRUPT ){ - char *zQ2; - int len = strlen(zQuery); - if( pzErrMsg ) sqlite3_free(*pzErrMsg); - zQ2 = malloc( len+100 ); - if( zQ2==0 ) return rc; - sprintf(zQ2, "%s ORDER BY rowid DESC", zQuery); - rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg); - free(zQ2); - } - return rc; -} - -/* -** Text of a help message -*/ -static char zHelp[] = - ".databases List names and files of attached databases\n" - ".dump ?TABLE? ... Dump the database in an SQL text format\n" - ".echo ON|OFF Turn command echo on or off\n" - ".exit Exit this program\n" - ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n" - ".header(s) ON|OFF Turn display of headers on or off\n" - ".help Show this message\n" - ".import FILE TABLE Import data from FILE into TABLE\n" - ".indices TABLE Show names of all indices on TABLE\n" - ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" - " csv Comma-separated values\n" - " column Left-aligned columns. (See .width)\n" - " html HTML
%s
"); - output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); - fprintf(p->out,"
code\n" - " insert SQL insert statements for TABLE\n" - " line One value per line\n" - " list Values delimited by .separator string\n" - " tabs Tab-separated values\n" - " tcl TCL list elements\n" - ".nullvalue STRING Print STRING in place of NULL values\n" - ".output FILENAME Send output to FILENAME\n" - ".output stdout Send output to the screen\n" - ".prompt MAIN CONTINUE Replace the standard prompts\n" - ".quit Exit this program\n" - ".read FILENAME Execute SQL in FILENAME\n" -#ifdef SQLITE_HAS_CODEC - ".rekey OLD NEW NEW Change the encryption key\n" -#endif - ".schema ?TABLE? Show the CREATE statements\n" - ".separator STRING Change separator used by output mode and .import\n" - ".show Show the current values for various settings\n" - ".tables ?PATTERN? List names of tables matching a LIKE pattern\n" - ".timeout MS Try opening locked tables for MS milliseconds\n" - ".width NUM NUM ... Set column widths for \"column\" mode\n" -; - -/* Forward reference */ -static void process_input(struct callback_data *p, FILE *in); - -/* -** Make sure the database is open. If it is not, then open it. If -** the database fails to open, print an error message and exit. -*/ -static void open_db(struct callback_data *p){ - if( p->db==0 ){ - sqlite3_open(p->zDbFilename, &p->db); - db = p->db; -#ifdef SQLITE_HAS_CODEC - sqlite3_key(p->db, p->zKey, p->zKey ? strlen(p->zKey) : 0); -#endif - sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0, - shellstaticFunc, 0, 0); - if( SQLITE_OK!=sqlite3_errcode(db) ){ - fprintf(stderr,"Unable to open database \"%s\": %s\n", - p->zDbFilename, sqlite3_errmsg(db)); - exit(1); - } - } -} - -/* -** Do C-language style dequoting. -** -** \t -> tab -** \n -> newline -** \r -> carriage return -** \NNN -> ascii character NNN in octal -** \\ -> backslash -*/ -static void resolve_backslashes(char *z){ - int i, j, c; - for(i=j=0; (c = z[i])!=0; i++, j++){ - if( c=='\\' ){ - c = z[++i]; - if( c=='n' ){ - c = '\n'; - }else if( c=='t' ){ - c = '\t'; - }else if( c=='r' ){ - c = '\r'; - }else if( c>='0' && c<='7' ){ - c =- '0'; - if( z[i+1]>='0' && z[i+1]<='7' ){ - i++; - c = (c<<3) + z[i] - '0'; - if( z[i+1]>='0' && z[i+1]<='7' ){ - i++; - c = (c<<3) + z[i] - '0'; - } - } - } - } - z[j] = c; - } - z[j] = 0; -} - -/* -** If an input line begins with "." then invoke this routine to -** process that line. -** -** Return 1 to exit and 0 to continue. -*/ -static int do_meta_command(char *zLine, struct callback_data *p){ - int i = 1; - int nArg = 0; - int n, c; - int rc = 0; - char *azArg[50]; - - /* Parse the input line into tokens. - */ - while( zLine[i] && nArg1 && strncmp(azArg[0], "databases", n)==0 ){ - struct callback_data data; - char *zErrMsg = 0; - open_db(p); - memcpy(&data, p, sizeof(data)); - data.showHeader = 1; - data.mode = MODE_Column; - data.colWidth[0] = 3; - data.colWidth[1] = 15; - data.colWidth[2] = 58; - data.cnt = 0; - sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); - if( zErrMsg ){ - fprintf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - } - }else - - if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ - char *zErrMsg = 0; - open_db(p); - fprintf(p->out, "BEGIN TRANSACTION;\n"); - if( nArg==1 ){ - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND type=='table'", 0 - ); - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND type!='table' AND type!='meta'", 0 - ); - }else{ - int i; - for(i=1; iout, "COMMIT;\n"); - } - }else - - if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){ - int j; - char *z = azArg[1]; - int val = atoi(azArg[1]); - for(j=0; z[j]; j++){ - z[j] = tolower((unsigned char)z[j]); - } - if( strcmp(z,"on")==0 ){ - val = 1; - }else if( strcmp(z,"yes")==0 ){ - val = 1; - } - p->echoOn = val; - }else - - if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ - rc = 1; - }else - - if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){ - int j; - static char zOne[] = "1"; - char *z = nArg>=2 ? azArg[1] : zOne; - int val = atoi(z); - for(j=0; z[j]; j++){ - z[j] = tolower((unsigned char)z[j]); - } - if( strcmp(z,"on")==0 ){ - val = 1; - }else if( strcmp(z,"yes")==0 ){ - val = 1; - } - if(val == 1) { - if(!p->explainPrev.valid) { - p->explainPrev.valid = 1; - p->explainPrev.mode = p->mode; - p->explainPrev.showHeader = p->showHeader; - memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth)); - } - /* We could put this code under the !p->explainValid - ** condition so that it does not execute if we are already in - ** explain mode. However, always executing it allows us an easy - ** was to reset to explain mode in case the user previously - ** did an .explain followed by a .width, .mode or .header - ** command. - */ - p->mode = MODE_Column; - p->showHeader = 1; - memset(p->colWidth,0,ArraySize(p->colWidth)); - p->colWidth[0] = 4; - p->colWidth[1] = 12; - p->colWidth[2] = 10; - p->colWidth[3] = 10; - p->colWidth[4] = 35; - }else if (p->explainPrev.valid) { - p->explainPrev.valid = 0; - p->mode = p->explainPrev.mode; - p->showHeader = p->explainPrev.showHeader; - memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth)); - } - }else - - if( c=='h' && (strncmp(azArg[0], "header", n)==0 - || - strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){ - int j; - char *z = azArg[1]; - int val = atoi(azArg[1]); - for(j=0; z[j]; j++){ - z[j] = tolower((unsigned char)z[j]); - } - if( strcmp(z,"on")==0 ){ - val = 1; - }else if( strcmp(z,"yes")==0 ){ - val = 1; - } - p->showHeader = val; - }else - - if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ - fprintf(stderr,zHelp); - }else - - if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){ - char *zTable = azArg[2]; /* Insert data into this table */ - char *zFile = azArg[1]; /* The file from which to extract data */ - sqlite3_stmt *pStmt; /* A statement */ - int rc; /* Result code */ - int nCol; /* Number of columns in the table */ - int nByte; /* Number of bytes in an SQL string */ - int i, j; /* Loop counters */ - int nSep; /* Number of bytes in p->separator[] */ - char *zSql; /* An SQL statement */ - char *zLine; /* A single line of input from the file */ - char **azCol; /* zLine[] broken up into columns */ - char *zCommit; /* How to commit changes */ - FILE *in; /* The input file */ - int lineno = 0; /* Line number of input file */ - - nSep = strlen(p->separator); - if( nSep==0 ){ - fprintf(stderr, "non-null separator required for import\n"); - return 0; - } - zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); - if( zSql==0 ) return 0; - nByte = strlen(zSql); - rc = sqlite3_prepare(p->db, zSql, 0, &pStmt, 0); - sqlite3_free(zSql); - if( rc ){ - fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); - nCol = 0; - }else{ - nCol = sqlite3_column_count(pStmt); - } - sqlite3_finalize(pStmt); - if( nCol==0 ) return 0; - zSql = malloc( nByte + 20 + nCol*2 ); - if( zSql==0 ) return 0; - sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable); - j = strlen(zSql); - for(i=1; idb, zSql, 0, &pStmt, 0); - free(zSql); - if( rc ){ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); - sqlite3_finalize(pStmt); - return 0; - } - in = fopen(zFile, "rb"); - if( in==0 ){ - fprintf(stderr, "cannot open file: %s\n", zFile); - sqlite3_finalize(pStmt); - return 0; - } - azCol = malloc( sizeof(azCol[0])*(nCol+1) ); - if( azCol==0 ) return 0; - sqlite3_exec(p->db, "BEGIN", 0, 0, 0); - zCommit = "COMMIT"; - while( (zLine = local_getline(0, in))!=0 ){ - char *z; - i = 0; - lineno++; - azCol[0] = zLine; - for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){ - if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){ - *z = 0; - i++; - if( idb, zCommit, 0, 0, 0); - }else - - if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){ - struct callback_data data; - char *zErrMsg = 0; - open_db(p); - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.mode = MODE_List; - zShellStatic = azArg[1]; - sqlite3_exec(p->db, - "SELECT name FROM sqlite_master " - "WHERE type='index' AND tbl_name LIKE shellstatic() " - "UNION ALL " - "SELECT name FROM sqlite_temp_master " - "WHERE type='index' AND tbl_name LIKE shellstatic() " - "ORDER BY 1", - callback, &data, &zErrMsg - ); - zShellStatic = 0; - if( zErrMsg ){ - fprintf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - } - }else - - if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){ - int n2 = strlen(azArg[1]); - if( strncmp(azArg[1],"line",n2)==0 - || - strncmp(azArg[1],"lines",n2)==0 ){ - p->mode = MODE_Line; - }else if( strncmp(azArg[1],"column",n2)==0 - || - strncmp(azArg[1],"columns",n2)==0 ){ - p->mode = MODE_Column; - }else if( strncmp(azArg[1],"list",n2)==0 ){ - p->mode = MODE_List; - }else if( strncmp(azArg[1],"html",n2)==0 ){ - p->mode = MODE_Html; - }else if( strncmp(azArg[1],"tcl",n2)==0 ){ - p->mode = MODE_Tcl; - }else if( strncmp(azArg[1],"csv",n2)==0 ){ - p->mode = MODE_Csv; - strcpy(p->separator, ","); - }else if( strncmp(azArg[1],"tabs",n2)==0 ){ - p->mode = MODE_List; - strcpy(p->separator, "\t"); - }else if( strncmp(azArg[1],"insert",n2)==0 ){ - p->mode = MODE_Insert; - if( nArg>=3 ){ - set_table_name(p, azArg[2]); - }else{ - set_table_name(p, "table"); - } - }else { - fprintf(stderr,"mode should be on of: " - "column csv html insert line list tabs tcl\n"); - } - }else - - if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) { - sprintf(p->nullvalue, "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); - }else - - if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){ - if( p->out!=stdout ){ - fclose(p->out); - } - if( strcmp(azArg[1],"stdout")==0 ){ - p->out = stdout; - strcpy(p->outfile,"stdout"); - }else{ - p->out = fopen(azArg[1], "wb"); - if( p->out==0 ){ - fprintf(stderr,"can't write to \"%s\"\n", azArg[1]); - p->out = stdout; - } else { - strcpy(p->outfile,azArg[1]); - } - } - }else - - if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){ - if( nArg >= 2) { - strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); - } - if( nArg >= 3) { - strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1); - } - }else - - if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ - rc = 1; - }else - - if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){ - FILE *alt = fopen(azArg[1], "rb"); - if( alt==0 ){ - fprintf(stderr,"can't open \"%s\"\n", azArg[1]); - }else{ - process_input(p, alt); - fclose(alt); - } - }else - -#ifdef SQLITE_HAS_CODEC - if( c=='r' && strncmp(azArg[0],"rekey", n)==0 && nArg==4 ){ - char *zOld = p->zKey; - if( zOld==0 ) zOld = ""; - if( strcmp(azArg[1],zOld) ){ - fprintf(stderr,"old key is incorrect\n"); - }else if( strcmp(azArg[2], azArg[3]) ){ - fprintf(stderr,"2nd copy of new key does not match the 1st\n"); - }else{ - sqlite3_free(p->zKey); - p->zKey = sqlite3_mprintf("%s", azArg[2]); - sqlite3_rekey(p->db, p->zKey, strlen(p->zKey)); - } - }else -#endif - - if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ - struct callback_data data; - char *zErrMsg = 0; - open_db(p); - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.mode = MODE_Semi; - if( nArg>1 ){ - int i; - for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]); - if( strcmp(azArg[1],"sqlite_master")==0 ){ - char *new_argv[2], *new_colv[2]; - new_argv[0] = "CREATE TABLE sqlite_master (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")"; - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); - }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){ - char *new_argv[2], *new_colv[2]; - new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")"; - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); - }else{ - zShellStatic = azArg[1]; - sqlite3_exec(p->db, - "SELECT sql FROM " - " (SELECT * FROM sqlite_master UNION ALL" - " SELECT * FROM sqlite_temp_master) " - "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL " - "ORDER BY substr(type,2,1), name", - callback, &data, &zErrMsg); - zShellStatic = 0; - } - }else{ - sqlite3_exec(p->db, - "SELECT sql FROM " - " (SELECT * FROM sqlite_master UNION ALL" - " SELECT * FROM sqlite_temp_master) " - "WHERE type!='meta' AND sql NOTNULL " - "ORDER BY substr(type,2,1), name", - callback, &data, &zErrMsg - ); - } - if( zErrMsg ){ - fprintf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - } - }else - - if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){ - sprintf(p->separator, "%.*s", (int)ArraySize(p->separator)-1, azArg[1]); - }else - - if( c=='s' && strncmp(azArg[0], "show", n)==0){ - int i; - fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off"); - fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off"); - fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off"); - fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]); - fprintf(p->out,"%9.9s: ", "nullvalue"); - output_c_string(p->out, p->nullvalue); - fprintf(p->out, "\n"); - fprintf(p->out,"%9.9s: %s\n","output", - strlen(p->outfile) ? p->outfile : "stdout"); - fprintf(p->out,"%9.9s: ", "separator"); - output_c_string(p->out, p->separator); - fprintf(p->out, "\n"); - fprintf(p->out,"%9.9s: ","width"); - for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { - fprintf(p->out,"%d ",p->colWidth[i]); - } - fprintf(p->out,"\n"); - }else - - if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){ - char **azResult; - int nRow, rc; - char *zErrMsg; - open_db(p); - if( nArg==1 ){ - rc = sqlite3_get_table(p->db, - "SELECT name FROM sqlite_master " - "WHERE type IN ('table','view') " - "UNION ALL " - "SELECT name FROM sqlite_temp_master " - "WHERE type IN ('table','view') " - "ORDER BY 1", - &azResult, &nRow, 0, &zErrMsg - ); - }else{ - zShellStatic = azArg[1]; - rc = sqlite3_get_table(p->db, - "SELECT name FROM sqlite_master " - "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' " - "UNION ALL " - "SELECT name FROM sqlite_temp_master " - "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' " - "ORDER BY 1", - &azResult, &nRow, 0, &zErrMsg - ); - zShellStatic = 0; - } - if( zErrMsg ){ - fprintf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - } - if( rc==SQLITE_OK ){ - int len, maxlen = 0; - int i, j; - int nPrintCol, nPrintRow; - for(i=1; i<=nRow; i++){ - if( azResult[i]==0 ) continue; - len = strlen(azResult[i]); - if( len>maxlen ) maxlen = len; - } - nPrintCol = 80/(maxlen+2); - if( nPrintCol<1 ) nPrintCol = 1; - nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; - for(i=0; i1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){ - open_db(p); - sqlite3_busy_timeout(p->db, atoi(azArg[1])); - }else - - if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ - int j; - for(j=1; jcolWidth); j++){ - p->colWidth[j-1] = atoi(azArg[j]); - } - }else - - { - fprintf(stderr, "unknown command or invalid arguments: " - " \"%s\". Enter \".help\" for help\n", azArg[0]); - } - - return rc; -} - -/* -** Return TRUE if the last non-whitespace character in z[] is a semicolon. -** z[] is N characters long. -*/ -static int _ends_with_semicolon(const char *z, int N){ - while( N>0 && isspace((unsigned char)z[N-1]) ){ N--; } - return N>0 && z[N-1]==';'; -} - -/* -** Test to see if a line consists entirely of whitespace. -*/ -static int _all_whitespace(const char *z){ - for(; *z; z++){ - if( isspace(*(unsigned char*)z) ) continue; - if( *z=='/' && z[1]=='*' ){ - z += 2; - while( *z && (*z!='*' || z[1]!='/') ){ z++; } - if( *z==0 ) return 0; - z++; - continue; - } - if( *z=='-' && z[1]=='-' ){ - z += 2; - while( *z && *z!='\n' ){ z++; } - if( *z==0 ) return 1; - continue; - } - return 0; - } - return 1; -} - -/* -** Return TRUE if the line typed in is an SQL command terminator other -** than a semi-colon. The SQL Server style "go" command is understood -** as is the Oracle "/". -*/ -static int _is_command_terminator(const char *zLine){ - while( isspace(*(unsigned char*)zLine) ){ zLine++; }; - if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */ - if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o' - && _all_whitespace(&zLine[2]) ){ - return 1; /* SQL Server */ - } - return 0; -} - -/* -** Read input from *in and process it. If *in==0 then input -** is interactive - the user is typing it it. Otherwise, input -** is coming from a file or device. A prompt is issued and history -** is saved only if input is interactive. An interrupt signal will -** cause this routine to exit immediately, unless input is interactive. -*/ -static void process_input(struct callback_data *p, FILE *in){ - char *zLine; - char *zSql = 0; - int nSql = 0; - char *zErrMsg; - int rc; - while( fflush(p->out), (zLine = one_input_line(zSql, in))!=0 ){ - if( seenInterrupt ){ - if( in!=0 ) break; - seenInterrupt = 0; - } - if( p->echoOn ) printf("%s\n", zLine); - if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue; - if( zLine && zLine[0]=='.' && nSql==0 ){ - int rc = do_meta_command(zLine, p); - free(zLine); - if( rc ) break; - continue; - } - if( _is_command_terminator(zLine) ){ - strcpy(zLine,";"); - } - if( zSql==0 ){ - int i; - for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){} - if( zLine[i]!=0 ){ - nSql = strlen(zLine); - zSql = malloc( nSql+1 ); - strcpy(zSql, zLine); - } - }else{ - int len = strlen(zLine); - zSql = realloc( zSql, nSql + len + 2 ); - if( zSql==0 ){ - fprintf(stderr,"%s: out of memory!\n", Argv0); - exit(1); - } - strcpy(&zSql[nSql++], "\n"); - strcpy(&zSql[nSql], zLine); - nSql += len; - } - free(zLine); - if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite3_complete(zSql) ){ - p->cnt = 0; - open_db(p); - rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg); - if( rc || zErrMsg ){ - if( in!=0 && !p->echoOn ) printf("%s\n",zSql); - if( zErrMsg!=0 ){ - printf("SQL error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - zErrMsg = 0; - }else{ - printf("SQL error: %s\n", sqlite3_errmsg(p->db)); - } - } - free(zSql); - zSql = 0; - nSql = 0; - } - } - if( zSql ){ - if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql); - free(zSql); - } -} - -/* -** Return a pathname which is the user's home directory. A -** 0 return indicates an error of some kind. Space to hold the -** resulting string is obtained from malloc(). The calling -** function should free the result. -*/ -static char *find_home_dir(void){ - char *home_dir = NULL; - -#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) - struct passwd *pwent; - uid_t uid = getuid(); - if( (pwent=getpwuid(uid)) != NULL) { - home_dir = pwent->pw_dir; - } -#endif - -#ifdef __MACOS__ - char home_path[_MAX_PATH+1]; - home_dir = getcwd(home_path, _MAX_PATH); -#endif - - if (!home_dir) { - home_dir = getenv("HOME"); - if (!home_dir) { - home_dir = getenv("HOMEPATH"); /* Windows? */ - } - } - -#if defined(_WIN32) || defined(WIN32) - if (!home_dir) { - home_dir = "c:"; - } -#endif - - if( home_dir ){ - char *z = malloc( strlen(home_dir)+1 ); - if( z ) strcpy(z, home_dir); - home_dir = z; - } - - return home_dir; -} - -/* -** Read input from the file given by sqliterc_override. Or if that -** parameter is NULL, take input from ~/.sqliterc -*/ -static void process_sqliterc( - struct callback_data *p, /* Configuration data */ - const char *sqliterc_override /* Name of config file. NULL to use default */ -){ - char *home_dir = NULL; - const char *sqliterc = sqliterc_override; - char *zBuf; - FILE *in = NULL; - - if (sqliterc == NULL) { - home_dir = find_home_dir(); - if( home_dir==0 ){ - fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0); - return; - } - zBuf = malloc(strlen(home_dir) + 15); - if( zBuf==0 ){ - fprintf(stderr,"%s: out of memory!\n", Argv0); - exit(1); - } - sprintf(zBuf,"%s/.sqliterc",home_dir); - free(home_dir); - sqliterc = (const char*)zBuf; - } - in = fopen(sqliterc,"rb"); - if( in ){ - if( isatty(fileno(stdout)) ){ - printf("Loading resources from %s\n",sqliterc); - } - process_input(p,in); - fclose(in); - } - return; -} - -/* -** Show available command line options -*/ -static const char zOptions[] = - " -init filename read/process named file\n" - " -echo print commands before execution\n" - " -[no]header turn headers on or off\n" - " -column set output mode to 'column'\n" - " -html set output mode to HTML\n" -#ifdef SQLITE_HAS_CODEC - " -key KEY encryption key\n" -#endif - " -line set output mode to 'line'\n" - " -list set output mode to 'list'\n" - " -separator 'x' set output field separator (|)\n" - " -nullvalue 'text' set text string for NULL values\n" - " -version show SQLite version\n" - " -help show this text, also show dot-commands\n" -; -static void usage(int showDetail){ - fprintf(stderr, "Usage: %s [OPTIONS] FILENAME [SQL]\n", Argv0); - if( showDetail ){ - fprintf(stderr, "Options are:\n%s", zOptions); - }else{ - fprintf(stderr, "Use the -help option for additional information\n"); - } - exit(1); -} - -/* -** Initialize the state information in data -*/ -void main_init(struct callback_data *data) { - memset(data, 0, sizeof(*data)); - data->mode = MODE_List; - strcpy(data->separator,"|"); - data->showHeader = 0; - strcpy(mainPrompt,"sqlite> "); - strcpy(continuePrompt," ...> "); -} - -int main(int argc, char **argv){ - char *zErrMsg = 0; - struct callback_data data; - const char *zInitFile = 0; - char *zFirstCmd = 0; - int i; - -#ifdef __MACOS__ - argc = ccommand(&argv); -#endif - - Argv0 = argv[0]; - main_init(&data); - - /* Make sure we have a valid signal handler early, before anything - ** else is done. - */ -#ifdef SIGINT - signal(SIGINT, interrupt_handler); -#endif - - /* Do an initial pass through the command-line argument to locate - ** the name of the database file, the name of the initialization file, - ** and the first command to execute. - */ - for(i=1; i /* 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 "--VERS--" - -/* -** The format of the version string is "X.Y.Z", where -** X is the major version number, Y is the minor version number and Z -** is the release number. The trailing string is often "alpha" or "beta". -** For example "3.1.1beta". -** -** The SQLITE_VERSION_NUMBER is an integer with the value -** (X*100000 + Y*1000 + Z). For example, for version "3.1.1beta", -** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using -** version 3.1.1 or greater at compile time, programs may use the test -** (SQLITE_VERSION_NUMBER>=3001001). -*/ -#ifdef SQLITE_VERSION_NUMBER -# undef SQLITE_VERSION_NUMBER -#endif -#define SQLITE_VERSION_NUMBER --VERSION-NUMBER-- - -/* -** The version string is also compiled into the library so that a program -** 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. -** -******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** -*/ -int sqlite3_clear_bindings(sqlite3_stmt*); - -/* -** Return the number of columns in the result set returned by the compiled -** SQL statement. This routine returns 0 if pStmt is an SQL statement -** 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. -** -******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** -*/ -int sqlite3_sleep(int); - -/* -** Return TRUE (non-zero) of the statement supplied as an argument needs -** to be recompiled. A statement needs to be recompiled whenever the -** execution environment changes in a way that would alter the program -** that sqlite3_prepare() generates. For example, if new functions or -** collating sequences are registered or if an authorizer function is -** added or changed. -** -******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** -*/ -int sqlite3_expired(sqlite3_stmt*); - -/* -** If the following global variable is made to point to a -** string which is the name of a directory, then all temporary files -** created by SQLite will be placed in that directory. If this variable -** is NULL pointer, then SQLite does a search for an appropriate temporary -** file directory. -** -** Once sqlite3_open() has been called, changing this variable will invalidate the -** current temporary database, if any. -*/ -extern char *sqlite3_temp_directory; - -#ifdef __cplusplus -} /* End of the 'extern "C"' block */ -#endif -#endif diff --git a/sqlite/src/sqliteInt.h b/sqlite/src/sqliteInt.h deleted file mode 100644 index c79e617..0000000 --- a/sqlite/src/sqliteInt.h +++ /dev/null @@ -1,1549 +0,0 @@ -/* -** 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.370 2005/02/09 01:40:25 danielk1977 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 "config.h" -#include "sqlite3.h" -#include "hash.h" -#include "parse.h" -#include -#include -#include -#include -#include - -/* -** 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 - -/* -** 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 -#ifndef INTPTR_TYPE -# if SQLITE_PTR_SZ==4 -# define INTPTR_TYPE int -# else -# define INTPTR_TYPE sqlite_int64 -# endif -#endif -#ifndef UINTPTR_TYPE -# if SQLITE_PTR_SZ==4 -# define UINTPTR_TYPE unsigned int -# else -# define UINTPTR_TYPE sqlite_uint64 -# endif -#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 */ -typedef INTPTR_TYPE ptr; /* Big enough to hold a pointer */ -typedef UINTPTR_TYPE uptr; /* Big enough to hold a pointer */ - -/* -** 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) (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 Instruction Instruction; -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; -typedef struct Fetch Fetch; - -/* -** 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 */ - Db aDbStatic[2]; /* Static space for the 2 default backends */ - int flags; /* Miscellanous flags. See below */ - 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 */ - BusyHandler busyHandler; /* Busy callback */ - void *pCommitArg; /* Argument to xCommitCallback() */ - int (*xCommitCallback)(void*);/* Invoked at every commit. */ - Hash aFunc; /* All functions that can be in SQL exprs */ - Hash aCollSeq; /* All collating sequences */ - 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 */ -#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 - int errCode; /* Most recent error code (SQLITE_*) */ - u8 enc; /* Text encoding for this database. */ - u8 autoCommit; /* The auto-commit flag. */ - 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) */ -}; - -/* -** 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 */ - 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 */ -}; - -/* -** 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 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. -*/ -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 " IN (fillAgg==FALSE, pull - ** result from the iAgg-th element of the aggregator */ - int iAggCtx; /* The value to pass as P1 of OP_AggGet. */ - Select *pSelect; /* When the expression is a sub-select. Also the - ** right side of " IN (
_" -# -# Then check that it is an error to try to drop any automtically created -# indices. -do_test index-17.1 { - execsql { - DROP TABLE t7; - CREATE TABLE t7(c, d UNIQUE, UNIQUE(c), PRIMARY KEY(c, d) ); - SELECT name FROM sqlite_master WHERE tbl_name = 't7' AND type = 'index'; - } -} {sqlite_autoindex_t7_1 sqlite_autoindex_t7_2 sqlite_autoindex_t7_3} -do_test index-17.2 { - catchsql { - DROP INDEX sqlite_autoindex_t7_1; - } -} {1 {index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped}} - -# The following tests ensure that it is not possible to explicitly name -# a schema object with a name beginning with "sqlite_". Granted that is a -# little outside the focus of this test scripts, but this has got to be -# tested somewhere. -do_test index-18.1 { - catchsql { - CREATE TABLE sqlite_t1(a, b, c); - } -} {1 {object name reserved for internal use: sqlite_t1}} -do_test index-18.2 { - catchsql { - CREATE INDEX sqlite_i1 ON t7(c); - } -} {1 {object name reserved for internal use: sqlite_i1}} -ifcapable view { -do_test index-18.3 { - catchsql { - CREATE VIEW sqlite_v1 AS SELECT * FROM t7; - } -} {1 {object name reserved for internal use: sqlite_v1}} -} ;# ifcapable view -ifcapable {trigger} { - do_test index-18.4 { - catchsql { - CREATE TRIGGER sqlite_tr1 BEFORE INSERT ON t7 BEGIN SELECT 1; END; - } - } {1 {object name reserved for internal use: sqlite_tr1}} -} -do_test index-18.5 { - execsql { - DROP TABLE t7; - } -} {} - -# These tests ensure that if multiple table definition constraints are -# implemented by a single indice, the correct ON CONFLICT policy applies. -do_test index-19.1 { - execsql { - CREATE TABLE t7(a UNIQUE PRIMARY KEY); - CREATE TABLE t8(a UNIQUE PRIMARY KEY ON CONFLICT ROLLBACK); - INSERT INTO t7 VALUES(1); - INSERT INTO t8 VALUES(1); - } -} {} -do_test index-19.2 { - catchsql { - BEGIN; - INSERT INTO t7 VALUES(1); - } -} {1 {column a is not unique}} -do_test index-19.3 { - catchsql { - BEGIN; - } -} {1 {cannot start a transaction within a transaction}} -do_test index-19.4 { - catchsql { - INSERT INTO t8 VALUES(1); - } -} {1 {column a is not unique}} -do_test index-19.5 { - catchsql { - BEGIN; - COMMIT; - } -} {0 {}} -do_test index-19.6 { - catchsql { - DROP TABLE t7; - DROP TABLE t8; - CREATE TABLE t7( - a PRIMARY KEY ON CONFLICT FAIL, - UNIQUE(a) ON CONFLICT IGNORE - ); - } -} {1 {conflicting ON CONFLICT clauses specified}} - -ifcapable {reindex} { - do_test index-19.7 { - execsql REINDEX - } {} -} -integrity_check index-19.8 - -# Drop index with a quoted name. Ticket #695. -# -do_test index-20.1 { - execsql { - CREATE INDEX "t6i2" ON t6(c); - DROP INDEX "t6i2"; - } -} {} -do_test index-20.2 { - execsql { - DROP INDEX "t6i1"; - } -} {} - - -finish_test diff --git a/sqlite/test/index2.test b/sqlite/test/index2.test deleted file mode 100644 index 174212c..0000000 --- a/sqlite/test/index2.test +++ /dev/null @@ -1,74 +0,0 @@ -# 2005 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 implements regression tests for SQLite library. The -# focus of this file is testing the CREATE INDEX statement. -# -# $Id: index2.test,v 1.2 2005/01/20 02:17:02 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Create a table with a large number of columns -# -do_test index2-1.1 { - set sql {CREATE TABLE t1(} - for {set i 1} {$i<1000} {incr i} { - append sql "c$i," - } - append sql "c1000);" - execsql $sql -} {} -do_test index2-1.2 { - set sql {INSERT INTO t1 VALUES(} - for {set i 1} {$i<1000} {incr i} { - append sql $i, - } - append sql {1000);} - execsql $sql -} {} -do_test index2-1.3 { - execsql {SELECT c123 FROM t1} -} 123 -do_test index2-1.4 { - execsql BEGIN - for {set j 1} {$j<=100} {incr j} { - set sql {INSERT INTO t1 VALUES(} - for {set i 1} {$i<1000} {incr i} { - append sql [expr {$j*10000+$i}], - } - append sql "[expr {$j*10000+1000}]);" - execsql $sql - } - execsql COMMIT - execsql {SELECT count(*) FROM t1} -} 101 -do_test index2-1.5 { - execsql {SELECT round(sum(c1000)) FROM t1} -} {50601000} - -# Create indices with many columns -# -do_test index2-2.1 { - set sql "CREATE INDEX t1i1 ON t1(" - for {set i 1} {$i<1000} {incr i} { - append sql c$i, - } - append sql c1000) - execsql $sql -} {} -do_test index2-2.2 { - ifcapable explain { - execsql {EXPLAIN SELECT c9 FROM t1 ORDER BY c1, c2, c3, c4, c5} - } - execsql {SELECT c9 FROM t1 ORDER BY c1, c2, c3, c4, c5, c6 LIMIT 5} -} {9 10009 20009 30009 40009} - -finish_test diff --git a/sqlite/test/index3.test b/sqlite/test/index3.test deleted file mode 100644 index b744574..0000000 --- a/sqlite/test/index3.test +++ /dev/null @@ -1,43 +0,0 @@ -# 2005 February 14 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this file is testing the CREATE INDEX statement. -# -# $Id: index3.test,v 1.1 2005/02/14 20:48:19 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Ticket #1115. Make sure that when a UNIQUE index is created on a -# non-unique column (or columns) that it fails and that it leaves no -# residue behind. -# -do_test index3-1.1 { - execsql { - CREATE TABLE t1(a); - INSERT INTO t1 VALUES(1); - INSERT INTO t1 VALUES(1); - SELECT * FROM t1; - } -} {1 1} -do_test index3-1.2 { - catchsql { - BEGIN; - CREATE UNIQUE INDEX i1 ON t1(a); - } -} {1 {indexed columns are not unique}} -do_test index3-1.3 { - catchsql COMMIT; -} {0 {}} -integrity_check index3-1.4 - -finish_test diff --git a/sqlite/test/insert.test b/sqlite/test/insert.test deleted file mode 100644 index 9fc9b23..0000000 --- a/sqlite/test/insert.test +++ /dev/null @@ -1,345 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the INSERT statement. -# -# $Id: insert.test,v 1.23 2005/01/21 03:12:16 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Try to insert into a non-existant table. -# -do_test insert-1.1 { - set v [catch {execsql {INSERT INTO test1 VALUES(1,2,3)}} msg] - lappend v $msg -} {1 {no such table: test1}} - -# Try to insert into sqlite_master -# -do_test insert-1.2 { - set v [catch {execsql {INSERT INTO sqlite_master VALUES(1,2,3,4)}} msg] - lappend v $msg -} {1 {table sqlite_master may not be modified}} - -# Try to insert the wrong number of entries. -# -do_test insert-1.3 { - execsql {CREATE TABLE test1(one int, two int, three int)} - set v [catch {execsql {INSERT INTO test1 VALUES(1,2)}} msg] - lappend v $msg -} {1 {table test1 has 3 columns but 2 values were supplied}} -do_test insert-1.3b { - set v [catch {execsql {INSERT INTO test1 VALUES(1,2,3,4)}} msg] - lappend v $msg -} {1 {table test1 has 3 columns but 4 values were supplied}} -do_test insert-1.3c { - set v [catch {execsql {INSERT INTO test1(one,two) VALUES(1,2,3,4)}} msg] - lappend v $msg -} {1 {4 values for 2 columns}} -do_test insert-1.3d { - set v [catch {execsql {INSERT INTO test1(one,two) VALUES(1)}} msg] - lappend v $msg -} {1 {1 values for 2 columns}} - -# Try to insert into a non-existant column of a table. -# -do_test insert-1.4 { - set v [catch {execsql {INSERT INTO test1(one,four) VALUES(1,2)}} msg] - lappend v $msg -} {1 {table test1 has no column named four}} - -# Make sure the inserts actually happen -# -do_test insert-1.5 { - execsql {INSERT INTO test1 VALUES(1,2,3)} - execsql {SELECT * FROM test1} -} {1 2 3} -do_test insert-1.5b { - execsql {INSERT INTO test1 VALUES(4,5,6)} - execsql {SELECT * FROM test1 ORDER BY one} -} {1 2 3 4 5 6} -do_test insert-1.5c { - execsql {INSERT INTO test1 VALUES(7,8,9)} - execsql {SELECT * FROM test1 ORDER BY one} -} {1 2 3 4 5 6 7 8 9} - -do_test insert-1.6 { - execsql {DELETE FROM test1} - execsql {INSERT INTO test1(one,two) VALUES(1,2)} - execsql {SELECT * FROM test1 ORDER BY one} -} {1 2 {}} -do_test insert-1.6b { - execsql {INSERT INTO test1(two,three) VALUES(5,6)} - execsql {SELECT * FROM test1 ORDER BY one} -} {{} 5 6 1 2 {}} -do_test insert-1.6c { - execsql {INSERT INTO test1(three,one) VALUES(7,8)} - execsql {SELECT * FROM test1 ORDER BY one} -} {{} 5 6 1 2 {} 8 {} 7} - -# A table to use for testing default values -# -do_test insert-2.1 { - execsql { - CREATE TABLE test2( - f1 int default -111, - f2 real default +4.32, - f3 int default +222, - f4 int default 7.89 - ) - } - execsql {SELECT * from test2} -} {} -do_test insert-2.2 { - execsql {INSERT INTO test2(f1,f3) VALUES(+10,-10)} - execsql {SELECT * FROM test2} -} {10 4.32 -10 7.89} -do_test insert-2.3 { - execsql {INSERT INTO test2(f2,f4) VALUES(1.23,-3.45)} - execsql {SELECT * FROM test2 WHERE f1==-111} -} {-111 1.23 222 -3.45} -do_test insert-2.4 { - execsql {INSERT INTO test2(f1,f2,f4) VALUES(77,+1.23,3.45)} - execsql {SELECT * FROM test2 WHERE f1==77} -} {77 1.23 222 3.45} -do_test insert-2.10 { - execsql { - DROP TABLE test2; - CREATE TABLE test2( - f1 int default 111, - f2 real default -4.32, - f3 text default hi, - f4 text default 'abc-123', - f5 varchar(10) - ) - } - execsql {SELECT * from test2} -} {} -do_test insert-2.11 { - execsql {INSERT INTO test2(f2,f4) VALUES(-2.22,'hi!')} - execsql {SELECT * FROM test2} -} {111 -2.22 hi hi! {}} -do_test insert-2.12 { - execsql {INSERT INTO test2(f1,f5) VALUES(1,'xyzzy')} - execsql {SELECT * FROM test2 ORDER BY f1} -} {1 -4.32 hi abc-123 xyzzy 111 -2.22 hi hi! {}} - -# Do additional inserts with default values, but this time -# on a table that has indices. In particular we want to verify -# that the correct default values are inserted into the indices. -# -do_test insert-3.1 { - execsql { - DELETE FROM test2; - CREATE INDEX index9 ON test2(f1,f2); - CREATE INDEX indext ON test2(f4,f5); - SELECT * from test2; - } -} {} - -# Update for sqlite3 v3: -# Change the 111 to '111' in the following two test cases, because -# the default value is being inserted as a string. TODO: It shouldn't be. -do_test insert-3.2 { - execsql {INSERT INTO test2(f2,f4) VALUES(-3.33,'hum')} - execsql {SELECT * FROM test2 WHERE f1='111' AND f2=-3.33} -} {111 -3.33 hi hum {}} -do_test insert-3.3 { - execsql {INSERT INTO test2(f1,f2,f5) VALUES(22,-4.44,'wham')} - execsql {SELECT * FROM test2 WHERE f1='111' AND f2=-3.33} -} {111 -3.33 hi hum {}} -do_test insert-3.4 { - execsql {SELECT * FROM test2 WHERE f1=22 AND f2=-4.44} -} {22 -4.44 hi abc-123 wham} -ifcapable {reindex} { - do_test insert-3.5 { - execsql REINDEX - } {} -} -integrity_check insert-3.5 - -# Test of expressions in the VALUES clause -# -do_test insert-4.1 { - execsql { - CREATE TABLE t3(a,b,c); - INSERT INTO t3 VALUES(1+2+3,4,5); - SELECT * FROM t3; - } -} {6 4 5} -do_test insert-4.2 { - ifcapable subquery { - execsql {INSERT INTO t3 VALUES((SELECT max(a) FROM t3)+1,5,6);} - } else { - set maxa [execsql {SELECT max(a) FROM t3}] - execsql "INSERT INTO t3 VALUES($maxa+1,5,6);" - } - execsql { - SELECT * FROM t3 ORDER BY a; - } -} {6 4 5 7 5 6} -ifcapable subquery { - do_test insert-4.3 { - catchsql { - INSERT INTO t3 VALUES((SELECT max(a) FROM t3)+1,t3.a,6); - SELECT * FROM t3 ORDER BY a; - } - } {1 {no such column: t3.a}} -} -do_test insert-4.4 { - ifcapable subquery { - execsql {INSERT INTO t3 VALUES((SELECT b FROM t3 WHERE a=0),6,7);} - } else { - set b [execsql {SELECT b FROM t3 WHERE a = 0}] - if {$b==""} {set b NULL} - execsql "INSERT INTO t3 VALUES($b,6,7);" - } - execsql { - SELECT * FROM t3 ORDER BY a; - } -} {{} 6 7 6 4 5 7 5 6} -do_test insert-4.5 { - execsql { - SELECT b,c FROM t3 WHERE a IS NULL; - } -} {6 7} -do_test insert-4.6 { - catchsql { - INSERT INTO t3 VALUES(notafunc(2,3),2,3); - } -} {1 {no such function: notafunc}} -do_test insert-4.7 { - execsql { - INSERT INTO t3 VALUES(min(1,2,3),max(1,2,3),99); - SELECT * FROM t3 WHERE c=99; - } -} {1 3 99} - -# Test the ability to insert from a temporary table into itself. -# Ticket #275. -# -do_test insert-5.1 { - execsql { - CREATE TEMP TABLE t4(x); - INSERT INTO t4 VALUES(1); - SELECT * FROM t4; - } -} {1} -do_test insert-5.2 { - execsql { - INSERT INTO t4 SELECT x+1 FROM t4; - SELECT * FROM t4; - } -} {1 2} -ifcapable {explain} { - do_test insert-5.3 { - # verify that a temporary table is used to copy t4 to t4 - set x [execsql { - EXPLAIN INSERT INTO t4 SELECT x+2 FROM t4; - }] - expr {[lsearch $x OpenTemp]>0} - } {1} -} - -do_test insert-5.4 { - # Verify that table "test1" begins on page 3. This should be the same - # page number used by "t4" above. - # - # Update for v3 - the first table now begins on page 2 of each file, not 3. - execsql { - SELECT rootpage FROM sqlite_master WHERE name='test1'; - } -} [expr $AUTOVACUUM?3:2] -do_test insert-5.5 { - # Verify that "t4" begins on page 3. - # - # Update for v3 - the first table now begins on page 2 of each file, not 3. - execsql { - SELECT rootpage FROM sqlite_temp_master WHERE name='t4'; - } -} {2} -do_test insert-5.6 { - # This should not use an intermediate temporary table. - execsql { - INSERT INTO t4 SELECT one FROM test1 WHERE three=7; - SELECT * FROM t4 - } -} {1 2 8} -ifcapable {explain} { - do_test insert-5.7 { - # verify that no temporary table is used to copy test1 to t4 - set x [execsql { - EXPLAIN INSERT INTO t4 SELECT one FROM test1; - }] - expr {[lsearch $x OpenTemp]>0} - } {0} -} - -# Ticket #334: REPLACE statement corrupting indices. -# -do_test insert-6.1 { - execsql { - CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE); - INSERT INTO t1 VALUES(1,2); - INSERT INTO t1 VALUES(2,3); - SELECT b FROM t1 WHERE b=2; - } -} {2} -do_test insert-6.2 { - execsql { - REPLACE INTO t1 VALUES(1,4); - SELECT b FROM t1 WHERE b=2; - } -} {} -do_test insert-6.3 { - execsql { - UPDATE OR REPLACE t1 SET a=2 WHERE b=4; - SELECT * FROM t1 WHERE b=4; - } -} {2 4} -do_test insert-6.4 { - execsql { - SELECT * FROM t1 WHERE b=3; - } -} {} -ifcapable {reindex} { - do_test insert-6.7 { - execsql REINDEX - } {} -} - -# Test that the special optimization for queries of the form -# "SELECT max(x) FROM tbl" where there is an index on tbl(x) works with -# INSERT statments. -do_test insert-7.1 { - execsql { - DROP TABLE t1; - CREATE TABLE t1(a); - INSERT INTO t1 VALUES(1); - INSERT INTO t1 VALUES(2); - CREATE INDEX i1 ON t1(a); - } -} {} -do_test insert-7.2 { - execsql { - INSERT INTO t1 SELECT max(a) FROM t1; - } -} {} -do_test insert-7.3 { - execsql { - SELECT a FROM t1; - } -} {1 2 2} - -integrity_check insert-99.0 - -finish_test diff --git a/sqlite/test/insert2.test b/sqlite/test/insert2.test deleted file mode 100644 index f213a9a..0000000 --- a/sqlite/test/insert2.test +++ /dev/null @@ -1,268 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the INSERT statement that takes is -# result from a SELECT. -# -# $Id: insert2.test,v 1.15 2005/02/08 08:42:29 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Create some tables with data that we can select against -# -do_test insert2-1.0 { - execsql {CREATE TABLE d1(n int, log int);} - for {set i 1} {$i<=20} {incr i} { - for {set j 0} {pow(2,$j)<$i} {incr j} {} - execsql "INSERT INTO d1 VALUES($i,$j)" - } - execsql {SELECT * FROM d1 ORDER BY n} -} {1 0 2 1 3 2 4 2 5 3 6 3 7 3 8 3 9 4 10 4 11 4 12 4 13 4 14 4 15 4 16 4 17 5 18 5 19 5 20 5} - -# Insert into a new table from the old one. -# -do_test insert2-1.1.1 { - execsql { - CREATE TABLE t1(log int, cnt int); - PRAGMA count_changes=on; - INSERT INTO t1 SELECT log, count(*) FROM d1 GROUP BY log; - } -} {6} -do_test insert2-1.1.2 { - db changes -} {6} -do_test insert2-1.1.3 { - execsql {SELECT * FROM t1 ORDER BY log} -} {0 1 1 1 2 2 3 4 4 8 5 4} - -ifcapable compound { -do_test insert2-1.2.1 { - catch {execsql {DROP TABLE t1}} - execsql { - CREATE TABLE t1(log int, cnt int); - INSERT INTO t1 - SELECT log, count(*) FROM d1 GROUP BY log - EXCEPT SELECT n-1,log FROM d1; - } -} {4} -do_test insert2-1.2.2 { - execsql { - SELECT * FROM t1 ORDER BY log; - } -} {0 1 3 4 4 8 5 4} -do_test insert2-1.3.1 { - catch {execsql {DROP TABLE t1}} - execsql { - CREATE TABLE t1(log int, cnt int); - PRAGMA count_changes=off; - INSERT INTO t1 - SELECT log, count(*) FROM d1 GROUP BY log - INTERSECT SELECT n-1,log FROM d1; - } -} {} -do_test insert2-1.3.2 { - execsql { - SELECT * FROM t1 ORDER BY log; - } -} {1 1 2 2} -} ;# ifcapable compound -execsql {PRAGMA count_changes=off;} - -do_test insert2-1.4 { - catch {execsql {DROP TABLE t1}} - set r [execsql { - CREATE TABLE t1(log int, cnt int); - CREATE INDEX i1 ON t1(log); - CREATE INDEX i2 ON t1(cnt); - INSERT INTO t1 SELECT log, count() FROM d1 GROUP BY log; - SELECT * FROM t1 ORDER BY log; - }] - lappend r [execsql {SELECT cnt FROM t1 WHERE log=3}] - lappend r [execsql {SELECT log FROM t1 WHERE cnt=4 ORDER BY log}] -} {0 1 1 1 2 2 3 4 4 8 5 4 4 {3 5}} - -do_test insert2-2.0 { - execsql { - CREATE TABLE t3(a,b,c); - CREATE TABLE t4(x,y); - INSERT INTO t4 VALUES(1,2); - SELECT * FROM t4; - } -} {1 2} -do_test insert2-2.1 { - execsql { - INSERT INTO t3(a,c) SELECT * FROM t4; - SELECT * FROM t3; - } -} {1 {} 2} -do_test insert2-2.2 { - execsql { - DELETE FROM t3; - INSERT INTO t3(c,b) SELECT * FROM t4; - SELECT * FROM t3; - } -} {{} 2 1} -do_test insert2-2.3 { - execsql { - DELETE FROM t3; - INSERT INTO t3(c,a,b) SELECT x, 'hi', y FROM t4; - SELECT * FROM t3; - } -} {hi 2 1} - -integrity_check insert2-3.0 - -# File table t4 with lots of data -# -do_test insert2-3.1 { - execsql { - SELECT * from t4; - } -} {1 2} -do_test insert2-3.2 { - set x [db total_changes] - execsql { - BEGIN; - INSERT INTO t4 VALUES(2,4); - INSERT INTO t4 VALUES(3,6); - INSERT INTO t4 VALUES(4,8); - INSERT INTO t4 VALUES(5,10); - INSERT INTO t4 VALUES(6,12); - INSERT INTO t4 VALUES(7,14); - INSERT INTO t4 VALUES(8,16); - INSERT INTO t4 VALUES(9,18); - INSERT INTO t4 VALUES(10,20); - COMMIT; - } - expr [db total_changes] - $x -} {9} -do_test insert2-3.2.1 { - execsql { - SELECT count(*) FROM t4; - } -} {10} -do_test insert2-3.3 { - ifcapable subquery { - execsql { - BEGIN; - INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4; - INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4; - INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4; - INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4; - COMMIT; - SELECT count(*) FROM t4; - } - } else { - db function max_x_t4 {execsql {SELECT max(x) FROM t4}} - execsql { - BEGIN; - INSERT INTO t4 SELECT x+max_x_t4() ,y FROM t4; - INSERT INTO t4 SELECT x+max_x_t4() ,y FROM t4; - INSERT INTO t4 SELECT x+max_x_t4() ,y FROM t4; - INSERT INTO t4 SELECT x+max_x_t4() ,y FROM t4; - COMMIT; - SELECT count(*) FROM t4; - } - } -} {160} -do_test insert2-3.4 { - execsql { - BEGIN; - UPDATE t4 SET y='lots of data for the row where x=' || x - || ' and y=' || y || ' - even more data to fill space'; - COMMIT; - SELECT count(*) FROM t4; - } -} {160} -do_test insert2-3.5 { - ifcapable subquery { - execsql { - BEGIN; - INSERT INTO t4 SELECT x+(SELECT max(x)+1 FROM t4),y FROM t4; - SELECT count(*) from t4; - ROLLBACK; - } - } else { - execsql { - BEGIN; - INSERT INTO t4 SELECT x+max_x_t4()+1,y FROM t4; - SELECT count(*) from t4; - ROLLBACK; - } - } -} {320} -do_test insert2-3.6 { - execsql { - SELECT count(*) FROM t4; - } -} {160} -do_test insert2-3.7 { - execsql { - BEGIN; - DELETE FROM t4 WHERE x!=123; - SELECT count(*) FROM t4; - ROLLBACK; - } -} {1} -do_test insert2-3.8 { - db changes -} {159} -integrity_check insert2-3.9 - -# Ticket #901 -# -do_test insert2-4.1 { - execsql { - CREATE TABLE Dependencies(depId integer primary key, - class integer, name str, flag str); - CREATE TEMPORARY TABLE DepCheck(troveId INT, depNum INT, - flagCount INT, isProvides BOOL, class INTEGER, name STRING, - flag STRING); - INSERT INTO DepCheck - VALUES(-1, 0, 1, 0, 2, 'libc.so.6', 'GLIBC_2.0'); - INSERT INTO Dependencies - SELECT DISTINCT - NULL, - DepCheck.class, - DepCheck.name, - DepCheck.flag - FROM DepCheck LEFT OUTER JOIN Dependencies ON - DepCheck.class == Dependencies.class AND - DepCheck.name == Dependencies.name AND - DepCheck.flag == Dependencies.flag - WHERE - Dependencies.depId is NULL; - }; -} {} - -#-------------------------------------------------------------------- -# Test that the INSERT works when the SELECT statement (a) references -# the table being inserted into and (b) is optimized to use an index -# only. -do_test insert2-5.1 { - execsql { - CREATE TABLE t2(a, b); - INSERT INTO t2 VALUES(1, 2); - CREATE INDEX t2i1 ON t2(a); - INSERT INTO t2 SELECT a, 3 FROM t2 WHERE a = 1; - SELECT * FROM t2; - } -} {1 2 1 3} -do_test insert2-5.2 { - execsql { - INSERT INTO t2 SELECT (SELECT a FROM t2), 4; - SELECT * FROM t2; - } -} {1 2 1 3 1 4} - -finish_test - diff --git a/sqlite/test/insert3.test b/sqlite/test/insert3.test deleted file mode 100644 index b2999ff..0000000 --- a/sqlite/test/insert3.test +++ /dev/null @@ -1,135 +0,0 @@ -# 2005 January 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 implements regression tests for SQLite library. The -# focus of this file is testing corner cases of the INSERT statement. -# -# $Id: insert3.test,v 1.3 2005/01/29 08:32:46 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# All the tests in this file require trigger support -# -ifcapable {trigger} { - -# Create a table and a corresponding insert trigger. Do a self-insert -# into the table. -# -do_test insert3-1.0 { - execsql { - CREATE TABLE t1(a,b); - CREATE TABLE log(x UNIQUE, y); - CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN - UPDATE log SET y=y+1 WHERE x=new.a; - INSERT OR IGNORE INTO log VALUES(new.a, 1); - END; - INSERT INTO t1 VALUES('hello','world'); - INSERT INTO t1 VALUES(5,10); - SELECT * FROM log ORDER BY x; - } -} {5 1 hello 1} -do_test insert3-1.1 { - execsql { - INSERT INTO t1 SELECT a, b+10 FROM t1; - SELECT * FROM log ORDER BY x; - } -} {5 2 hello 2} -do_test insert3-1.2 { - execsql { - CREATE TABLE log2(x PRIMARY KEY,y); - CREATE TRIGGER r2 BEFORE INSERT ON t1 BEGIN - UPDATE log2 SET y=y+1 WHERE x=new.b; - INSERT OR IGNORE INTO log2 VALUES(new.b,1); - END; - INSERT INTO t1 VALUES(453,'hi'); - SELECT * FROM log ORDER BY x; - } -} {5 2 453 1 hello 2} -do_test insert3-1.3 { - execsql { - SELECT * FROM log2 ORDER BY x; - } -} {hi 1} -ifcapable compound { - do_test insert3-1.4 { - execsql { - INSERT INTO t1 SELECT * FROM t1; - SELECT 'a:', x, y FROM log UNION ALL - SELECT 'b:', x, y FROM log2 ORDER BY x; - } - } {a: 5 4 b: 10 2 b: 20 1 a: 453 2 a: hello 4 b: hi 2 b: world 1} - do_test insert3-1.5 { - execsql { - INSERT INTO t1(a) VALUES('xyz'); - SELECT * FROM log ORDER BY x; - } - } {5 4 453 2 hello 4 xyz 1} -} - -do_test insert3-2.1 { - execsql { - CREATE TABLE t2( - a INTEGER PRIMARY KEY, - b DEFAULT 'b', - c DEFAULT 'c' - ); - CREATE TABLE t2dup(a,b,c); - CREATE TRIGGER t2r1 BEFORE INSERT ON t2 BEGIN - INSERT INTO t2dup(a,b,c) VALUES(new.a,new.b,new.c); - END; - INSERT INTO t2(a) VALUES(123); - INSERT INTO t2(b) VALUES(234); - INSERT INTO t2(c) VALUES(345); - SELECT * FROM t2dup; - } -} {123 b c -1 234 c -1 b 345} -do_test insert3-2.2 { - execsql { - DELETE FROM t2dup; - INSERT INTO t2(a) SELECT 1 FROM t1 LIMIT 1; - INSERT INTO t2(b) SELECT 987 FROM t1 LIMIT 1; - INSERT INTO t2(c) SELECT 876 FROM t1 LIMIT 1; - SELECT * FROM t2dup; - } -} {1 b c -1 987 c -1 b 876} - -# Test for proper detection of malformed WHEN clauses on INSERT triggers. -# -do_test insert3-3.1 { - execsql { - CREATE TABLE t3(a,b,c); - CREATE TRIGGER t3r1 BEFORE INSERT on t3 WHEN nosuchcol BEGIN - SELECT 'illegal WHEN clause'; - END; - } -} {} -do_test insert3-3.2 { - catchsql { - INSERT INTO t3 VALUES(1,2,3) - } -} {1 {no such column: nosuchcol}} -do_test insert3-3.3 { - execsql { - CREATE TABLE t4(a,b,c); - CREATE TRIGGER t4r1 AFTER INSERT on t4 WHEN nosuchcol BEGIN - SELECT 'illegal WHEN clause'; - END; - } -} {} -do_test insert3-3.4 { - catchsql { - INSERT INTO t4 VALUES(1,2,3) - } -} {1 {no such column: nosuchcol}} - -} ;# ifcapable {trigger} - -finish_test diff --git a/sqlite/test/interrupt.test b/sqlite/test/interrupt.test deleted file mode 100644 index 4633471..0000000 --- a/sqlite/test/interrupt.test +++ /dev/null @@ -1,189 +0,0 @@ -# 2004 Feb 8 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this script is the sqlite_interrupt() API. -# -# $Id: interrupt.test,v 1.10 2005/01/11 17:46:42 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -db close -set DB [sqlite3 db test.db] - -# Compute a checksum on the entire database. -# -proc cksum {{db db}} { - set txt [$db eval {SELECT name, type, sql FROM sqlite_master}]\n - foreach tbl [$db eval {SELECT name FROM sqlite_master WHERE type='table'}] { - append txt [$db eval "SELECT * FROM $tbl"]\n - } - foreach prag {default_synchronous default_cache_size} { - append txt $prag-[$db eval "PRAGMA $prag"]\n - } - set cksum [string length $txt]-[md5 $txt] - # puts $cksum-[file size test.db] - return $cksum -} - -# This routine attempts to execute the sql in $sql. It triggers an -# interrupt a progressively later and later points during the processing -# and checks to make sure SQLITE_INTERRUPT is returned. Eventually, -# the routine completes successfully. -# -proc interrupt_test {testid sql result {initcnt 0}} { - set orig_sum [cksum] - set i $initcnt - while 1 { - incr i - set ::sqlite_interrupt_count $i - do_test $testid.$i.1 [format { - set ::r [catchsql %s] - set ::code [db errorcode] - expr {$::code==0 || $::code==9} - } [list $sql]] 1 - if {$::code==9} { - do_test $testid.$i.2 { - cksum - } $orig_sum - } else { - do_test $testid.$i.99 { - set ::r - } [list 0 $result] - break - } - } - set ::sqlite_interrupt_count 0 -} - -do_test interrupt-1.1 { - execsql { - CREATE TABLE t1(a,b); - SELECT name FROM sqlite_master; - } -} {t1} -interrupt_test interrupt-1.2 {DROP TABLE t1} {} -do_test interrupt-1.3 { - execsql { - SELECT name FROM sqlite_master; - } -} {} -integrity_check interrupt-1.4 - -do_test interrrupt-2.1 { - execsql { - BEGIN; - CREATE TABLE t1(a,b); - INSERT INTO t1 VALUES(1,randstr(300,400)); - INSERT INTO t1 SELECT a+1, randstr(300,400) FROM t1; - INSERT INTO t1 SELECT a+2, a || '-' || b FROM t1; - INSERT INTO t1 SELECT a+4, a || '-' || b FROM t1; - INSERT INTO t1 SELECT a+8, a || '-' || b FROM t1; - INSERT INTO t1 SELECT a+16, a || '-' || b FROM t1; - INSERT INTO t1 SELECT a+32, a || '-' || b FROM t1; - COMMIT; - UPDATE t1 SET b=substr(b,-5,5); - SELECT count(*) from t1; - } -} 64 -set origsize [file size test.db] -set cksum [db eval {SELECT md5sum(a || b) FROM t1}] -ifcapable {vacuum} { - interrupt_test interrupt-2.2 {VACUUM} {} 100 -} -do_test interrupt-2.3 { - execsql { - SELECT md5sum(a || b) FROM t1; - } -} $cksum -ifcapable {vacuum && !default_autovacuum} { - do_test interrupt-2.4 { - expr {$::origsize>[file size test.db]} - } 1 -} -ifcapable {explain} { - do_test interrupt-2.5 { - set sql {EXPLAIN SELECT max(a,b), a, b FROM t1} - execsql $sql - set rc [catch {db eval $sql {sqlite3_interrupt $DB}} msg] - lappend rc $msg - } {1 interrupted} -} -integrity_check interrupt-2.6 - -# Ticket #594. If an interrupt occurs in the middle of a transaction -# and that transaction is later rolled back, the internal schema tables do -# not reset. -# -for {set i 1} {$i<50} {incr i 5} { - do_test interrupt-3.$i.1 { - execsql { - BEGIN; - CREATE TEMP TABLE t2(x,y); - SELECT name FROM sqlite_temp_master; - } - } {t2} - do_test interrupt-3.$i.2 { - set ::sqlite_interrupt_count $::i - catchsql { - INSERT INTO t2 SELECT * FROM t1; - } - } {1 interrupted} - do_test interrupt-3.$i.3 { - execsql { - SELECT name FROM sqlite_temp_master; - } - } {t2} - do_test interrupt-3.$i.4 { - catchsql { - ROLLBACK - } - } {0 {}} - do_test interrupt-3.$i.5 { - catchsql {SELECT name FROM sqlite_temp_master}; - execsql { - SELECT name FROM sqlite_temp_master; - } - } {} -} - -# There are reports of a memory leak if an interrupt occurs during -# the beginning of a complex query - before the first callback. We -# will try to reproduce it here: -# -execsql { - CREATE TABLE t2(a,b,c); - INSERT INTO t2 SELECT round(a/10), randstr(50,80), randstr(50,60) FROM t1; -} -set sql { - SELECT max(min(b,c)), min(max(b,c)), a FROM t2 GROUP BY a ORDER BY a; -} -set sqlite_interrupt_count 1000000 -execsql $sql -set max_count [expr {1000000-$sqlite_interrupt_count}] -for {set i 1} {$i<$max_count-5} {incr i 1} { - do_test interrupt-4.$i.1 { - set ::sqlite_interrupt_count $::i - catchsql $sql - } {1 interrupted} -} - -# Interrupt during parsing -# -do_test interrupt-5.1 { - proc fake_interrupt {args} {sqlite3_interrupt $::DB; return SQLITE_OK} - db collation_needed fake_interrupt - catchsql { - CREATE INDEX fake ON fake1(a COLLATE fake_collation, b, c DESC); - } -} {1 interrupt} - -finish_test diff --git a/sqlite/test/intpkey.test b/sqlite/test/intpkey.test deleted file mode 100644 index cab7e84..0000000 --- a/sqlite/test/intpkey.test +++ /dev/null @@ -1,523 +0,0 @@ -# 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 implements regression tests for SQLite library. -# -# This file implements tests for the special processing associated -# with INTEGER PRIMARY KEY columns. -# -# $Id: intpkey.test,v 1.20 2004/11/03 13:59:06 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Create a table with a primary key and a datatype other than -# integer -# -do_test intpkey-1.0 { - execsql { - CREATE TABLE t1(a TEXT PRIMARY KEY, b, c); - } -} {} - -# There should be an index associated with the primary key -# -do_test intpkey-1.1 { - execsql { - SELECT name FROM sqlite_master - WHERE type='index' AND tbl_name='t1'; - } -} {sqlite_autoindex_t1_1} - -# Now create a table with an integer primary key and verify that -# there is no associated index. -# -do_test intpkey-1.2 { - execsql { - DROP TABLE t1; - CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); - SELECT name FROM sqlite_master - WHERE type='index' AND tbl_name='t1'; - } -} {} - -# Insert some records into the new table. Specify the primary key -# and verify that the key is used as the record number. -# -do_test intpkey-1.3 { - execsql { - INSERT INTO t1 VALUES(5,'hello','world'); - } - db last_insert_rowid -} {5} -do_test intpkey-1.4 { - execsql { - SELECT * FROM t1; - } -} {5 hello world} -do_test intpkey-1.5 { - execsql { - SELECT rowid, * FROM t1; - } -} {5 5 hello world} - -# Attempting to insert a duplicate primary key should give a constraint -# failure. -# -do_test intpkey-1.6 { - set r [catch {execsql { - INSERT INTO t1 VALUES(5,'second','entry'); - }} msg] - lappend r $msg -} {1 {PRIMARY KEY must be unique}} -do_test intpkey-1.7 { - execsql { - SELECT rowid, * FROM t1; - } -} {5 5 hello world} -do_test intpkey-1.8 { - set r [catch {execsql { - INSERT INTO t1 VALUES(6,'second','entry'); - }} msg] - lappend r $msg -} {0 {}} -do_test intpkey-1.8.1 { - db last_insert_rowid -} {6} -do_test intpkey-1.9 { - execsql { - SELECT rowid, * FROM t1; - } -} {5 5 hello world 6 6 second entry} - -# A ROWID is automatically generated for new records that do not specify -# the integer primary key. -# -do_test intpkey-1.10 { - execsql { - INSERT INTO t1(b,c) VALUES('one','two'); - SELECT b FROM t1 ORDER BY b; - } -} {hello one second} - -# Try to change the ROWID for the new entry. -# -do_test intpkey-1.11 { - execsql { - UPDATE t1 SET a=4 WHERE b='one'; - SELECT * FROM t1; - } -} {4 one two 5 hello world 6 second entry} - -# Make sure SELECT statements are able to use the primary key column -# as an index. -# -do_test intpkey-1.12 { - execsql { - SELECT * FROM t1 WHERE a==4; - } -} {4 one two} - -# Try to insert a non-integer value into the primary key field. This -# should result in a data type mismatch. -# -do_test intpkey-1.13.1 { - set r [catch {execsql { - INSERT INTO t1 VALUES('x','y','z'); - }} msg] - lappend r $msg -} {1 {datatype mismatch}} -do_test intpkey-1.13.2 { - set r [catch {execsql { - INSERT INTO t1 VALUES('','y','z'); - }} msg] - lappend r $msg -} {1 {datatype mismatch}} -do_test intpkey-1.14 { - set r [catch {execsql { - INSERT INTO t1 VALUES(3.4,'y','z'); - }} msg] - lappend r $msg -} {1 {datatype mismatch}} -do_test intpkey-1.15 { - set r [catch {execsql { - INSERT INTO t1 VALUES(-3,'y','z'); - }} msg] - lappend r $msg -} {0 {}} -do_test intpkey-1.16 { - execsql {SELECT * FROM t1} -} {-3 y z 4 one two 5 hello world 6 second entry} - -#### INDICES -# Check to make sure indices work correctly with integer primary keys -# -do_test intpkey-2.1 { - execsql { - CREATE INDEX i1 ON t1(b); - SELECT * FROM t1 WHERE b=='y' - } -} {-3 y z} -do_test intpkey-2.1.1 { - execsql { - SELECT * FROM t1 WHERE b=='y' AND rowid<0 - } -} {-3 y z} -do_test intpkey-2.1.2 { - execsql { - SELECT * FROM t1 WHERE b=='y' AND rowid<0 AND rowid>=-20 - } -} {-3 y z} -do_test intpkey-2.1.3 { - execsql { - SELECT * FROM t1 WHERE b>='y' - } -} {-3 y z} -do_test intpkey-2.1.4 { - execsql { - SELECT * FROM t1 WHERE b>='y' AND rowid<10 - } -} {-3 y z} - -do_test intpkey-2.2 { - execsql { - UPDATE t1 SET a=8 WHERE b=='y'; - SELECT * FROM t1 WHERE b=='y'; - } -} {8 y z} -do_test intpkey-2.3 { - execsql { - SELECT rowid, * FROM t1; - } -} {4 4 one two 5 5 hello world 6 6 second entry 8 8 y z} -do_test intpkey-2.4 { - execsql { - SELECT rowid, * FROM t1 WHERE b<'second' - } -} {5 5 hello world 4 4 one two} -do_test intpkey-2.4.1 { - execsql { - SELECT rowid, * FROM t1 WHERE 'second'>b - } -} {5 5 hello world 4 4 one two} -do_test intpkey-2.4.2 { - execsql { - SELECT rowid, * FROM t1 WHERE 8>rowid AND 'second'>b - } -} {4 4 one two 5 5 hello world} -do_test intpkey-2.4.3 { - execsql { - SELECT rowid, * FROM t1 WHERE 8>rowid AND 'second'>b AND 0'a' - } -} {5 5 hello world 4 4 one two 6 6 second entry 8 8 y z} -do_test intpkey-2.6 { - execsql { - DELETE FROM t1 WHERE rowid=4; - SELECT * FROM t1 WHERE b>'a'; - } -} {5 hello world 6 second entry 8 y z} -do_test intpkey-2.7 { - execsql { - UPDATE t1 SET a=-4 WHERE rowid=8; - SELECT * FROM t1 WHERE b>'a'; - } -} {5 hello world 6 second entry -4 y z} -do_test intpkey-2.7 { - execsql { - SELECT * FROM t1 - } -} {-4 y z 5 hello world 6 second entry} - -# Do an SQL statement. Append the search count to the end of the result. -# -proc count sql { - set ::sqlite_search_count 0 - return [concat [execsql $sql] $::sqlite_search_count] -} - -# Create indices that include the integer primary key as one of their -# columns. -# -do_test intpkey-3.1 { - execsql { - CREATE INDEX i2 ON t1(a); - } -} {} -do_test intpkey-3.2 { - count { - SELECT * FROM t1 WHERE a=5; - } -} {5 hello world 0} -do_test intpkey-3.3 { - count { - SELECT * FROM t1 WHERE a>4 AND a<6; - } -} {5 hello world 2} -do_test intpkey-3.4 { - count { - SELECT * FROM t1 WHERE b>='hello' AND b<'hello2'; - } -} {5 hello world 3} -do_test intpkey-3.5 { - execsql { - CREATE INDEX i3 ON t1(c,a); - } -} {} -do_test intpkey-3.6 { - count { - SELECT * FROM t1 WHERE c=='world'; - } -} {5 hello world 3} -do_test intpkey-3.7 { - execsql {INSERT INTO t1 VALUES(11,'hello','world')} - count { - SELECT * FROM t1 WHERE c=='world'; - } -} {5 hello world 11 hello world 5} -do_test intpkey-3.8 { - count { - SELECT * FROM t1 WHERE c=='world' AND a>7; - } -} {11 hello world 5} -do_test intpkey-3.9 { - count { - SELECT * FROM t1 WHERE 7=oid; - } -} {11 hello world 1} -do_test intpkey-4.9 { - count { - SELECT * FROM t1 WHERE 11<=_rowid_ AND 12>=a; - } -} {11 hello world 1} -do_test intpkey-4.10 { - count { - SELECT * FROM t1 WHERE 0>=_rowid_; - } -} {-4 y z 1} -do_test intpkey-4.11 { - count { - SELECT * FROM t1 WHERE a<0; - } -} {-4 y z 1} -do_test intpkey-4.12 { - count { - SELECT * FROM t1 WHERE a<0 AND a>10; - } -} {1} - -# Make sure it is OK to insert a rowid of 0 -# -do_test intpkey-5.1 { - execsql { - INSERT INTO t1 VALUES(0,'zero','entry'); - } - count { - SELECT * FROM t1 WHERE a=0; - } -} {0 zero entry 0} -do_test intpkey-5.2 { - execsql { - SELECT rowid, a FROM t1 - } -} {-4 -4 0 0 5 5 6 6 11 11} - -# Test the ability of the COPY command to put data into a -# table that contains an integer primary key. -# -# COPY command has been removed. But we retain these tests so -# that the tables will contain the right data for tests that follow. -# -do_test intpkey-6.1 { - execsql { - BEGIN; - INSERT INTO t1 VALUES(20,'b-20','c-20'); - INSERT INTO t1 VALUES(21,'b-21','c-21'); - INSERT INTO t1 VALUES(22,'b-22','c-22'); - COMMIT; - SELECT * FROM t1 WHERE a>=20; - } -} {20 b-20 c-20 21 b-21 c-21 22 b-22 c-22} -do_test intpkey-6.2 { - execsql { - SELECT * FROM t1 WHERE b=='hello' - } -} {5 hello world 11 hello world} -do_test intpkey-6.3 { - execsql { - DELETE FROM t1 WHERE b='b-21'; - SELECT * FROM t1 WHERE b=='b-21'; - } -} {} -do_test intpkey-6.4 { - execsql { - SELECT * FROM t1 WHERE a>=20 - } -} {20 b-20 c-20 22 b-22 c-22} - -# Do an insert of values with the columns specified out of order. -# -do_test intpkey-7.1 { - execsql { - INSERT INTO t1(c,b,a) VALUES('row','new',30); - SELECT * FROM t1 WHERE rowid>=30; - } -} {30 new row} -do_test intpkey-7.2 { - execsql { - SELECT * FROM t1 WHERE rowid>20; - } -} {22 b-22 c-22 30 new row} - -# Do an insert from a select statement. -# -do_test intpkey-8.1 { - execsql { - CREATE TABLE t2(x INTEGER PRIMARY KEY, y, z); - INSERT INTO t2 SELECT * FROM t1; - SELECT rowid FROM t2; - } -} {-4 0 5 6 11 20 22 30} -do_test intpkey-8.2 { - execsql { - SELECT x FROM t2; - } -} {-4 0 5 6 11 20 22 30} - -do_test intpkey-9.1 { - execsql { - UPDATE t1 SET c='www' WHERE c='world'; - SELECT rowid, a, c FROM t1 WHERE c=='www'; - } -} {5 5 www 11 11 www} - - -# Check insert of NULL for primary key -# -do_test intpkey-10.1 { - execsql { - DROP TABLE t2; - CREATE TABLE t2(x INTEGER PRIMARY KEY, y, z); - INSERT INTO t2 VALUES(NULL, 1, 2); - SELECT * from t2; - } -} {1 1 2} -do_test intpkey-10.2 { - execsql { - INSERT INTO t2 VALUES(NULL, 2, 3); - SELECT * from t2 WHERE x=2; - } -} {2 2 3} -do_test intpkey-10.3 { - execsql { - INSERT INTO t2 SELECT NULL, z, y FROM t2; - SELECT * FROM t2; - } -} {1 1 2 2 2 3 3 2 1 4 3 2} - -# This tests checks to see if a floating point number can be used -# to reference an integer primary key. -# -do_test intpkey-11.1 { - execsql { - SELECT b FROM t1 WHERE a=2.0+3.0; - } -} {hello} -do_test intpkey-11.1 { - execsql { - SELECT b FROM t1 WHERE a=2.0+3.5; - } -} {} - -integrity_check intpkey-12.1 - -# Try to use a string that looks like a floating point number as -# an integer primary key. This should actually work when the floating -# point value can be rounded to an integer without loss of data. -# -do_test intpkey-13.1 { - execsql { - SELECT * FROM t1 WHERE a=1; - } -} {} -do_test intpkey-13.2 { - execsql { - INSERT INTO t1 VALUES('1.0',2,3); - SELECT * FROM t1 WHERE a=1; - } -} {1 2 3} -do_test intpkey-13.3 { - catchsql { - INSERT INTO t1 VALUES('1.5',3,4); - } -} {1 {datatype mismatch}} -ifcapable {bloblit} { - do_test intpkey-13.4 { - catchsql { - INSERT INTO t1 VALUES(x'123456',3,4); - } - } {1 {datatype mismatch}} -} -do_test intpkey-13.5 { - catchsql { - INSERT INTO t1 VALUES('+1234567890',3,4); - } -} {0 {}} - - -finish_test diff --git a/sqlite/test/ioerr.test b/sqlite/test/ioerr.test deleted file mode 100644 index 4ae7c60..0000000 --- a/sqlite/test/ioerr.test +++ /dev/null @@ -1,189 +0,0 @@ -# 2001 October 12 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this file is testing for correct handling of I/O errors -# such as writes failing because the disk is full. -# -# The tests in this file use special facilities that are only -# available in the SQLite test fixture. -# -# $Id: ioerr.test,v 1.19 2005/01/29 09:14:05 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error -# on the 8th IO operation in the SQL script below doesn't report an error. -# -# This is because the 8th IO call attempts to read page 2 of the database -# file when the file on disk is only 1 page. The pager layer detects that -# this has happened and suppresses the error returned by the OS layer. -# -do_ioerr_test ioerr-1 -sqlprep { - SELECT * FROM sqlite_master; -} -sqlbody { - CREATE TABLE t1(a,b,c); - SELECT * FROM sqlite_master; - BEGIN TRANSACTION; - INSERT INTO t1 VALUES(1,2,3); - INSERT INTO t1 VALUES(4,5,6); - ROLLBACK; - SELECT * FROM t1; - BEGIN TRANSACTION; - INSERT INTO t1 VALUES(1,2,3); - INSERT INTO t1 VALUES(4,5,6); - COMMIT; - SELECT * FROM t1; - DELETE FROM t1 WHERE a<100; -} -exclude [expr [string match [execsql {pragma auto_vacuum}] 1] ? 8 : 0] - -# Test for IO errors during a VACUUM. -# -# The first IO call is excluded from the test. This call attempts to read -# the file-header of the temporary database used by VACUUM. Since the -# database doesn't exist at that point, the IO error is not detected. -# -# Additionally, if auto-vacuum is enabled, the 12th IO error is not -# detected. Same reason as the 8th in the test case above. -# -ifcapable vacuum { - do_ioerr_test ioerr-2 -cksum true -sqlprep { - BEGIN; - CREATE TABLE t1(a, b, c); - INSERT INTO t1 VALUES(1, randstr(50,50), randstr(50,50)); - INSERT INTO t1 SELECT a+2, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT a+4, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT a+8, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT a+16, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT a+32, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT a+64, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT a+128, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 VALUES(1, randstr(600,600), randstr(600,600)); - CREATE TABLE t2 AS SELECT * FROM t1; - CREATE TABLE t3 AS SELECT * FROM t1; - COMMIT; - DROP TABLE t2; - } -sqlbody { - VACUUM; - } -exclude [list \ - 1 [expr [string match [execsql {pragma auto_vacuum}] 1]?12:-1]] -} - -do_ioerr_test ioerr-3 -tclprep { - execsql { - PRAGMA cache_size = 10; - BEGIN; - CREATE TABLE abc(a); - INSERT INTO abc VALUES(randstr(1500,1500)); -- Page 4 is overflow - } - for {set i 0} {$i<150} {incr i} { - execsql { - INSERT INTO abc VALUES(randstr(100,100)); - } - } - execsql COMMIT -} -sqlbody { - CREATE TABLE abc2(a); - BEGIN; - DELETE FROM abc WHERE length(a)>100; - UPDATE abc SET a = randstr(90,90); - COMMIT; - CREATE TABLE abc3(a); -} - -# Test IO errors that can occur retrieving a record header that flows over -# onto an overflow page. -do_ioerr_test ioerr-4 -tclprep { - set sql "CREATE TABLE abc(a1" - for {set i 2} {$i<1300} {incr i} { - append sql ", a$i" - } - append sql ");" - execsql $sql - execsql {INSERT INTO abc (a1) VALUES(NULL)} -} -sqlbody { - SELECT * FROM abc; -} - -# Test IO errors that may occur during a multi-file commit. -# -# Tests 8 and 17 are excluded when auto-vacuum is enabled for the same -# reason as in test cases ioerr-1.XXX -set ex "" -if {[string match [execsql {pragma auto_vacuum}] 1]} { - set ex [list 8 17] -} -do_ioerr_test ioerr-5 -sqlprep { - ATTACH 'test2.db' AS test2; -} -sqlbody { - BEGIN; - CREATE TABLE t1(a,b,c); - CREATE TABLE test2.t2(a,b,c); - COMMIT; -} -exclude $ex - -# Test IO errors when replaying two hot journals from a 2-file -# transaction. This test only runs on UNIX. -if {$tcl_platform(platform)=="unix" && [file exists ./crashtest]} { - do_ioerr_test ioerr-6 -tclprep { - execsql { - ATTACH 'test2.db' as aux; - CREATE TABLE tx(a, b); - CREATE TABLE aux.ty(a, b); - } - set rc [crashsql 2 test2.db-journal { - ATTACH 'test2.db' as aux; - PRAGMA cache_size = 10; - BEGIN; - CREATE TABLE aux.t2(a, b, c); - CREATE TABLE t1(a, b, c); - COMMIT; - }] - if {$rc!="1 {child process exited abnormally}"} { - error "Wrong error message: $rc" - } - } -sqlbody { - SELECT * FROM sqlite_master; - SELECT * FROM aux.sqlite_master; - } -} - -# Test handling of IO errors that occur while rolling back hot journal -# files. -# -# These tests can't be run on windows because the windows version of -# SQLite holds a mandatory exclusive lock on journal files it has open. -# -if {$tcl_platform(platform)!="windows"} { - do_ioerr_test ioerr-7 -tclprep { - db close - sqlite3 db2 test2.db - db2 eval { - PRAGMA synchronous = 0; - CREATE TABLE t1(a, b); - INSERT INTO t1 VALUES(1, 2); - BEGIN; - INSERT INTO t1 VALUES(3, 4); - } - copy_file test2.db test.db - copy_file test2.db-journal test.db-journal - db2 close - } -tclbody { - sqlite3 db test.db - db eval { - SELECT * FROM t1; - } - } -exclude 1 -} - -finish_test - - diff --git a/sqlite/test/join.test b/sqlite/test/join.test deleted file mode 100644 index c87b570..0000000 --- a/sqlite/test/join.test +++ /dev/null @@ -1,436 +0,0 @@ -# 2002 May 24 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# -# This file implements tests for joins, including outer joins. -# -# $Id: join.test,v 1.18 2005/01/21 15:52:33 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -do_test join-1.1 { - execsql { - CREATE TABLE t1(a,b,c); - INSERT INTO t1 VALUES(1,2,3); - INSERT INTO t1 VALUES(2,3,4); - INSERT INTO t1 VALUES(3,4,5); - SELECT * FROM t1; - } -} {1 2 3 2 3 4 3 4 5} -do_test join-1.2 { - execsql { - CREATE TABLE t2(b,c,d); - INSERT INTO t2 VALUES(1,2,3); - INSERT INTO t2 VALUES(2,3,4); - INSERT INTO t2 VALUES(3,4,5); - SELECT * FROM t2; - } -} {1 2 3 2 3 4 3 4 5} - -do_test join-1.3 { - execsql2 { - SELECT * FROM t1 NATURAL JOIN t2; - } -} {a 1 b 2 c 3 d 4 a 2 b 3 c 4 d 5} -do_test join-1.3.1 { - execsql2 { - SELECT * FROM t2 NATURAL JOIN t1; - } -} {b 2 c 3 d 4 a 1 b 3 c 4 d 5 a 2} -do_test join-1.3.2 { - execsql2 { - SELECT * FROM t2 AS x NATURAL JOIN t1; - } -} {b 2 c 3 d 4 a 1 b 3 c 4 d 5 a 2} -do_test join-1.3.3 { - execsql2 { - SELECT * FROM t2 NATURAL JOIN t1 AS y; - } -} {b 2 c 3 d 4 a 1 b 3 c 4 d 5 a 2} -do_test join-1.4.1 { - execsql2 { - SELECT * FROM t1 INNER JOIN t2 USING(b,c); - } -} {a 1 b 2 c 3 d 4 a 2 b 3 c 4 d 5} -do_test join-1.4.2 { - execsql2 { - SELECT * FROM t1 AS x INNER JOIN t2 USING(b,c); - } -} {a 1 b 2 c 3 d 4 a 2 b 3 c 4 d 5} -do_test join-1.4.3 { - execsql2 { - SELECT * FROM t1 INNER JOIN t2 AS y USING(b,c); - } -} {a 1 b 2 c 3 d 4 a 2 b 3 c 4 d 5} -do_test join-1.4.4 { - execsql2 { - SELECT * FROM t1 AS x INNER JOIN t2 AS y USING(b,c); - } -} {a 1 b 2 c 3 d 4 a 2 b 3 c 4 d 5} -do_test join-1.5 { - execsql2 { - SELECT * FROM t1 INNER JOIN t2 USING(b); - } -} {a 1 b 2 c 3 c 3 d 4 a 2 b 3 c 4 c 4 d 5} -do_test join-1.6 { - execsql2 { - SELECT * FROM t1 INNER JOIN t2 USING(c); - } -} {a 1 b 2 c 3 b 2 d 4 a 2 b 3 c 4 b 3 d 5} -do_test join-1.7 { - execsql2 { - SELECT * FROM t1 INNER JOIN t2 USING(c,b); - } -} {a 1 b 2 c 3 d 4 a 2 b 3 c 4 d 5} - -do_test join-1.8 { - execsql { - SELECT * FROM t1 NATURAL CROSS JOIN t2; - } -} {1 2 3 4 2 3 4 5} -do_test join-1.9 { - execsql { - SELECT * FROM t1 CROSS JOIN t2 USING(b,c); - } -} {1 2 3 4 2 3 4 5} -do_test join-1.10 { - execsql { - SELECT * FROM t1 NATURAL INNER JOIN t2; - } -} {1 2 3 4 2 3 4 5} -do_test join-1.11 { - execsql { - SELECT * FROM t1 INNER JOIN t2 USING(b,c); - } -} {1 2 3 4 2 3 4 5} -do_test join-1.12 { - execsql { - SELECT * FROM t1 natural inner join t2; - } -} {1 2 3 4 2 3 4 5} - -ifcapable subquery { - do_test join-1.13 { - execsql2 { - SELECT * FROM t1 NATURAL JOIN - (SELECT b as 'c', c as 'd', d as 'e' FROM t2) as t3 - } - } {a 1 b 2 c 3 d 4 e 5} - do_test join-1.14 { - execsql2 { - SELECT * FROM (SELECT b as 'c', c as 'd', d as 'e' FROM t2) as 'tx' - NATURAL JOIN t1 - } - } {c 3 d 4 e 5 a 1 b 2} -} - -do_test join-1.15 { - execsql { - CREATE TABLE t3(c,d,e); - INSERT INTO t3 VALUES(2,3,4); - INSERT INTO t3 VALUES(3,4,5); - INSERT INTO t3 VALUES(4,5,6); - SELECT * FROM t3; - } -} {2 3 4 3 4 5 4 5 6} -do_test join-1.16 { - execsql { - SELECT * FROM t1 natural join t2 natural join t3; - } -} {1 2 3 4 5 2 3 4 5 6} -do_test join-1.17 { - execsql2 { - SELECT * FROM t1 natural join t2 natural join t3; - } -} {a 1 b 2 c 3 d 4 e 5 a 2 b 3 c 4 d 5 e 6} -do_test join-1.18 { - execsql { - CREATE TABLE t4(d,e,f); - INSERT INTO t4 VALUES(2,3,4); - INSERT INTO t4 VALUES(3,4,5); - INSERT INTO t4 VALUES(4,5,6); - SELECT * FROM t4; - } -} {2 3 4 3 4 5 4 5 6} -do_test join-1.19.1 { - execsql { - SELECT * FROM t1 natural join t2 natural join t4; - } -} {1 2 3 4 5 6} -do_test join-1.19.2 { - execsql2 { - SELECT * FROM t1 natural join t2 natural join t4; - } -} {a 1 b 2 c 3 d 4 e 5 f 6} -do_test join-1.20 { - execsql { - SELECT * FROM t1 natural join t2 natural join t3 WHERE t1.a=1 - } -} {1 2 3 4 5} - -do_test join-2.1 { - execsql { - SELECT * FROM t1 NATURAL LEFT JOIN t2; - } -} {1 2 3 4 2 3 4 5 3 4 5 {}} -do_test join-2.2 { - execsql { - SELECT * FROM t2 NATURAL LEFT OUTER JOIN t1; - } -} {1 2 3 {} 2 3 4 1 3 4 5 2} -do_test join-2.3 { - catchsql { - SELECT * FROM t1 NATURAL RIGHT OUTER JOIN t2; - } -} {1 {RIGHT and FULL OUTER JOINs are not currently supported}} -do_test join-2.4 { - execsql { - SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.d - } -} {1 2 3 {} {} {} 2 3 4 {} {} {} 3 4 5 1 2 3} -do_test join-2.5 { - execsql { - SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.d WHERE t1.a>1 - } -} {2 3 4 {} {} {} 3 4 5 1 2 3} -do_test join-2.6 { - execsql { - SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.d WHERE t2.b IS NULL OR t2.b>1 - } -} {1 2 3 {} {} {} 2 3 4 {} {} {}} - -do_test join-3.1 { - catchsql { - SELECT * FROM t1 NATURAL JOIN t2 ON t1.a=t2.b; - } -} {1 {a NATURAL join may not have an ON or USING clause}} -do_test join-3.2 { - catchsql { - SELECT * FROM t1 NATURAL JOIN t2 USING(b); - } -} {1 {a NATURAL join may not have an ON or USING clause}} -do_test join-3.3 { - catchsql { - SELECT * FROM t1 JOIN t2 ON t1.a=t2.b USING(b); - } -} {1 {cannot have both ON and USING clauses in the same join}} -do_test join-3.4 { - catchsql { - SELECT * FROM t1 JOIN t2 USING(a); - } -} {1 {cannot join using column a - column not present in both tables}} -do_test join-3.5 { - catchsql { - SELECT * FROM t1 USING(a); - } -} {0 {1 2 3 2 3 4 3 4 5}} -do_test join-3.6 { - catchsql { - SELECT * FROM t1 JOIN t2 ON t3.a=t2.b; - } -} {1 {no such column: t3.a}} -do_test join-3.7 { - catchsql { - SELECT * FROM t1 INNER OUTER JOIN t2; - } -} {1 {unknown or unsupported join type: INNER OUTER}} -do_test join-3.7 { - catchsql { - SELECT * FROM t1 LEFT BOGUS JOIN t2; - } -} {1 {unknown or unsupported join type: LEFT BOGUS}} - -do_test join-4.1 { - execsql { - BEGIN; - CREATE TABLE t5(a INTEGER PRIMARY KEY); - CREATE TABLE t6(a INTEGER); - INSERT INTO t6 VALUES(NULL); - INSERT INTO t6 VALUES(NULL); - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - COMMIT; - } - execsql { - SELECT * FROM t6 NATURAL JOIN t5; - } -} {} -do_test join-4.2 { - execsql { - SELECT * FROM t6, t5 WHERE t6.at5.a; - } -} {} -do_test join-4.4 { - execsql { - UPDATE t6 SET a='xyz'; - SELECT * FROM t6 NATURAL JOIN t5; - } -} {} -do_test join-4.6 { - execsql { - SELECT * FROM t6, t5 WHERE t6.at5.a; - } -} {} -do_test join-4.8 { - execsql { - UPDATE t6 SET a=1; - SELECT * FROM t6 NATURAL JOIN t5; - } -} {} -do_test join-4.9 { - execsql { - SELECT * FROM t6, t5 WHERE t6.at5.a; - } -} {} - -do_test join-5.1 { - execsql { - BEGIN; - create table centros (id integer primary key, centro); - INSERT INTO centros VALUES(1,'xxx'); - create table usuarios (id integer primary key, nombre, apellidos, - idcentro integer); - INSERT INTO usuarios VALUES(1,'a','aa',1); - INSERT INTO usuarios VALUES(2,'b','bb',1); - INSERT INTO usuarios VALUES(3,'c','cc',NULL); - create index idcentro on usuarios (idcentro); - END; - select usuarios.id, usuarios.nombre, centros.centro from - usuarios left outer join centros on usuarios.idcentro = centros.id; - } -} {1 a xxx 2 b xxx 3 c {}} - -# A test for ticket #247. -# -do_test join-7.1 { - execsql { - CREATE TABLE t7 (x, y); - INSERT INTO t7 VALUES ("pa1", 1); - INSERT INTO t7 VALUES ("pa2", NULL); - INSERT INTO t7 VALUES ("pa3", NULL); - INSERT INTO t7 VALUES ("pa4", 2); - INSERT INTO t7 VALUES ("pa30", 131); - INSERT INTO t7 VALUES ("pa31", 130); - INSERT INTO t7 VALUES ("pa28", NULL); - - CREATE TABLE t8 (a integer primary key, b); - INSERT INTO t8 VALUES (1, "pa1"); - INSERT INTO t8 VALUES (2, "pa4"); - INSERT INTO t8 VALUES (3, NULL); - INSERT INTO t8 VALUES (4, NULL); - INSERT INTO t8 VALUES (130, "pa31"); - INSERT INTO t8 VALUES (131, "pa30"); - - SELECT coalesce(t8.a,999) from t7 LEFT JOIN t8 on y=a; - } -} {1 999 999 2 131 130 999} - -# Make sure a left join where the right table is really a view that -# is itself a join works right. Ticket #306. -# -ifcapable view { -do_test join-8.1 { - execsql { - BEGIN; - CREATE TABLE t9(a INTEGER PRIMARY KEY, b); - INSERT INTO t9 VALUES(1,11); - INSERT INTO t9 VALUES(2,22); - CREATE TABLE t10(x INTEGER PRIMARY KEY, y); - INSERT INTO t10 VALUES(1,2); - INSERT INTO t10 VALUES(3,3); - CREATE TABLE t11(p INTEGER PRIMARY KEY, q); - INSERT INTO t11 VALUES(2,111); - INSERT INTO t11 VALUES(3,333); - CREATE VIEW v10_11 AS SELECT x, q FROM t10, t11 WHERE t10.y=t11.p; - COMMIT; - SELECT * FROM t9 LEFT JOIN v10_11 ON( a=x ); - } -} {1 11 1 111 2 22 {} {}} -ifcapable subquery { - do_test join-8.2 { - execsql { - SELECT * FROM t9 LEFT JOIN (SELECT x, q FROM t10, t11 WHERE t10.y=t11.p) - ON( a=x); - } - } {1 11 1 111 2 22 {} {}} -} -do_test join-8.3 { - execsql { - SELECT * FROM v10_11 LEFT JOIN t9 ON( a=x ); - } -} {1 111 1 11 3 333 {} {}} -} ;# ifcapable view - -# Ticket #350 describes a scenario where LEFT OUTER JOIN does not -# function correctly if the right table in the join is really -# subquery. -# -# To test the problem, we generate the same LEFT OUTER JOIN in two -# separate selects but with on using a subquery and the other calling -# the table directly. Then connect the two SELECTs using an EXCEPT. -# Both queries should generate the same results so the answer should -# be an empty set. -# -ifcapable compound { -do_test join-9.1 { - execsql { - BEGIN; - CREATE TABLE t12(a,b); - INSERT INTO t12 VALUES(1,11); - INSERT INTO t12 VALUES(2,22); - CREATE TABLE t13(b,c); - INSERT INTO t13 VALUES(22,222); - COMMIT; - } -} {} - -ifcapable subquery { - do_test join-9.1.1 { - execsql { - SELECT * FROM t12 NATURAL LEFT JOIN t13 - EXCEPT - SELECT * FROM t12 NATURAL LEFT JOIN (SELECT * FROM t13 WHERE b>0); - } - } {} -} -ifcapable view { - do_test join-9.2 { - execsql { - CREATE VIEW v13 AS SELECT * FROM t13 WHERE b>0; - SELECT * FROM t12 NATURAL LEFT JOIN t13 - EXCEPT - SELECT * FROM t12 NATURAL LEFT JOIN v13; - } - } {} -} ;# ifcapable view -} ;# ifcapable compound - -finish_test diff --git a/sqlite/test/join2.test b/sqlite/test/join2.test deleted file mode 100644 index 0f558c5..0000000 --- a/sqlite/test/join2.test +++ /dev/null @@ -1,75 +0,0 @@ -# 2002 May 24 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# -# This file implements tests for joins, including outer joins. -# -# $Id: join2.test,v 1.2 2005/01/21 03:12:16 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -do_test join2-1.1 { - execsql { - CREATE TABLE t1(a,b); - INSERT INTO t1 VALUES(1,11); - INSERT INTO t1 VALUES(2,22); - INSERT INTO t1 VALUES(3,33); - SELECT * FROM t1; - } -} {1 11 2 22 3 33} -do_test join2-1.2 { - execsql { - CREATE TABLE t2(b,c); - INSERT INTO t2 VALUES(11,111); - INSERT INTO t2 VALUES(33,333); - INSERT INTO t2 VALUES(44,444); - SELECT * FROM t2; - } -} {11 111 33 333 44 444}; -do_test join2-1.3 { - execsql { - CREATE TABLE t3(c,d); - INSERT INTO t3 VALUES(111,1111); - INSERT INTO t3 VALUES(444,4444); - INSERT INTO t3 VALUES(555,5555); - SELECT * FROM t3; - } -} {111 1111 444 4444 555 5555} - -do_test join2-1.4 { - execsql { - SELECT * FROM - t1 NATURAL JOIN t2 NATURAL JOIN t3 - } -} {1 11 111 1111} -do_test join2-1.5 { - execsql { - SELECT * FROM - t1 NATURAL JOIN t2 NATURAL LEFT OUTER JOIN t3 - } -} {1 11 111 1111 3 33 333 {}} -do_test join2-1.6 { - execsql { - SELECT * FROM - t1 NATURAL LEFT OUTER JOIN t2 NATURAL JOIN t3 - } -} {1 11 111 1111} -ifcapable subquery { - do_test join2-1.7 { - execsql { - SELECT * FROM - t1 NATURAL LEFT OUTER JOIN (t2 NATURAL JOIN t3) - } - } {1 11 111 1111 2 22 {} {} 3 33 {} {}} -} - -finish_test diff --git a/sqlite/test/join3.test b/sqlite/test/join3.test deleted file mode 100644 index f1c273d..0000000 --- a/sqlite/test/join3.test +++ /dev/null @@ -1,62 +0,0 @@ -# 2002 May 24 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# -# This file implements tests for joins, including outer joins, where -# there are a large number of tables involved in the join. -# -# $Id: join3.test,v 1.4 2005/01/19 23:24:51 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# An unrestricted join -# -catch {unset ::result} -set result {} -for {set N 1} {$N<=$bitmask_size} {incr N} { - lappend result $N - do_test join3-1.$N { - execsql "CREATE TABLE t${N}(x);" - execsql "INSERT INTO t$N VALUES($N)" - set sql "SELECT * FROM t1" - for {set i 2} {$i<=$N} {incr i} {append sql ", t$i"} - execsql $sql - } $result -} - -# Joins with a comparison -# -set result {} -for {set N 1} {$N<=$bitmask_size} {incr N} { - lappend result $N - do_test join3-2.$N { - set sql "SELECT * FROM t1" - for {set i 2} {$i<=$N} {incr i} {append sql ", t$i"} - set sep WHERE - for {set i 1} {$i<$N} {incr i} { - append sql " $sep t[expr {$i+1}].x==t$i.x+1" - set sep AND - } - execsql $sql - } $result -} - -# Error of too many tables in the join -# -do_test join3-3.1 { - set sql "SELECT * FROM t1 AS t0, t1" - for {set i 2} {$i<=$bitmask_size} {incr i} {append sql ", t$i"} - catchsql $sql -} [list 1 "at most $bitmask_size tables in a join"] - - -finish_test diff --git a/sqlite/test/join4.test b/sqlite/test/join4.test deleted file mode 100644 index fba4425..0000000 --- a/sqlite/test/join4.test +++ /dev/null @@ -1,79 +0,0 @@ -# 2002 May 24 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# -# This file implements tests for left outer joins containing WHERE -# clauses that restrict the scope of the left term of the join. -# -# $Id: join4.test,v 1.3 2005/01/21 03:12:16 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -do_test join4-1.1 { - execsql { - create temp table t1(a integer, b varchar(10)); - insert into t1 values(1,'one'); - insert into t1 values(2,'two'); - insert into t1 values(3,'three'); - insert into t1 values(4,'four'); - - create temp table t2(x integer, y varchar(10), z varchar(10)); - insert into t2 values(2,'niban','ok'); - insert into t2 values(4,'yonban','err'); - } - execsql { - select * from t1 left outer join t2 on t1.a=t2.x where t2.z='ok' - } -} {2 two 2 niban ok} -do_test join4-1.2 { - execsql { - select * from t1 left outer join t2 on t1.a=t2.x and t2.z='ok' - } -} {1 one {} {} {} 2 two 2 niban ok 3 three {} {} {} 4 four {} {} {}} -do_test join4-1.3 { - execsql { - create index i2 on t2(z); - } - execsql { - select * from t1 left outer join t2 on t1.a=t2.x where t2.z='ok' - } -} {2 two 2 niban ok} -do_test join4-1.4 { - execsql { - select * from t1 left outer join t2 on t1.a=t2.x and t2.z='ok' - } -} {1 one {} {} {} 2 two 2 niban ok 3 three {} {} {} 4 four {} {} {}} -do_test join4-1.5 { - execsql { - select * from t1 left outer join t2 on t1.a=t2.x where t2.z>='ok' - } -} {2 two 2 niban ok} -do_test join4-1.4 { - execsql { - select * from t1 left outer join t2 on t1.a=t2.x and t2.z>='ok' - } -} {1 one {} {} {} 2 two 2 niban ok 3 three {} {} {} 4 four {} {} {}} -ifcapable subquery { - do_test join4-1.6 { - execsql { - select * from t1 left outer join t2 on t1.a=t2.x where t2.z IN ('ok') - } - } {2 two 2 niban ok} - do_test join4-1.7 { - execsql { - select * from t1 left outer join t2 on t1.a=t2.x and t2.z IN ('ok') - } - } {1 one {} {} {} 2 two 2 niban ok 3 three {} {} {} 4 four {} {} {}} -} - - -finish_test diff --git a/sqlite/test/lastinsert.test b/sqlite/test/lastinsert.test deleted file mode 100644 index f3ed2ec..0000000 --- a/sqlite/test/lastinsert.test +++ /dev/null @@ -1,346 +0,0 @@ -# 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. -# -#*********************************************************************** -# -# Tests to make sure that value returned by last_insert_rowid() (LIRID) -# is updated properly, especially inside triggers -# -# Note 1: insert into table is now the only statement which changes LIRID -# Note 2: upon entry into before or instead of triggers, -# LIRID is unchanged (rather than -1) -# Note 3: LIRID is changed within the context of a trigger, -# but is restored once the trigger exits -# Note 4: LIRID is not changed by an insert into a view (since everything -# is done within instead of trigger context) -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# ---------------------------------------------------------------------------- -# 1.x - basic tests (no triggers) - -# LIRID changed properly after an insert into a table -do_test lastinsert-1.1 { - catchsql { - create table t1 (k integer primary key); - insert into t1 values (1); - insert into t1 values (NULL); - insert into t1 values (NULL); - select last_insert_rowid(); - } -} {0 3} - -# LIRID unchanged after an update on a table -do_test lastinsert-1.2 { - catchsql { - update t1 set k=4 where k=2; - select last_insert_rowid(); - } -} {0 3} - -# LIRID unchanged after a delete from a table -do_test lastinsert-1.3 { - catchsql { - delete from t1 where k=4; - select last_insert_rowid(); - } -} {0 3} - -# LIRID unchanged after create table/view statements -do_test lastinsert-1.4.1 { - catchsql { - create table t2 (k integer primary key, val1, val2, val3); - select last_insert_rowid(); - } -} {0 3} -ifcapable view { -do_test lastinsert-1.4.2 { - catchsql { - create view v as select * from t1; - select last_insert_rowid(); - } -} {0 3} -} ;# ifcapable view - -# All remaining tests involve triggers. Skip them if triggers are not -# supported in this build. -# -ifcapable {!trigger} { - finish_test - return -} - -# ---------------------------------------------------------------------------- -# 2.x - tests with after insert trigger - -# LIRID changed properly after an insert into table containing an after trigger -do_test lastinsert-2.1 { - catchsql { - delete from t2; - create trigger r1 after insert on t1 for each row begin - insert into t2 values (NEW.k*2, last_insert_rowid(), NULL, NULL); - update t2 set k=k+10, val2=100+last_insert_rowid(); - update t2 set val3=1000+last_insert_rowid(); - end; - insert into t1 values (13); - select last_insert_rowid(); - } -} {0 13} - -# LIRID equals NEW.k upon entry into after insert trigger -do_test lastinsert-2.2 { - catchsql { - select val1 from t2; - } -} {0 13} - -# LIRID changed properly by insert within context of after insert trigger -do_test lastinsert-2.3 { - catchsql { - select val2 from t2; - } -} {0 126} - -# LIRID unchanged by update within context of after insert trigger -do_test lastinsert-2.4 { - catchsql { - select val3 from t2; - } -} {0 1026} - -# ---------------------------------------------------------------------------- -# 3.x - tests with after update trigger - -# LIRID not changed after an update onto a table containing an after trigger -do_test lastinsert-3.1 { - catchsql { - delete from t2; - drop trigger r1; - create trigger r1 after update on t1 for each row begin - insert into t2 values (NEW.k*2, last_insert_rowid(), NULL, NULL); - update t2 set k=k+10, val2=100+last_insert_rowid(); - update t2 set val3=1000+last_insert_rowid(); - end; - update t1 set k=14 where k=3; - select last_insert_rowid(); - } -} {0 13} - -# LIRID unchanged upon entry into after update trigger -do_test lastinsert-3.2 { - catchsql { - select val1 from t2; - } -} {0 13} - -# LIRID changed properly by insert within context of after update trigger -do_test lastinsert-3.3 { - catchsql { - select val2 from t2; - } -} {0 128} - -# LIRID unchanged by update within context of after update trigger -do_test lastinsert-3.4 { - catchsql { - select val3 from t2; - } -} {0 1028} - -# ---------------------------------------------------------------------------- -# 4.x - tests with instead of insert trigger -# These may not be run if either views or triggers were disabled at -# compile-time - -ifcapable {view && trigger} { -# LIRID not changed after an insert into view containing an instead of trigger -do_test lastinsert-4.1 { - catchsql { - delete from t2; - drop trigger r1; - create trigger r1 instead of insert on v for each row begin - insert into t2 values (NEW.k*2, last_insert_rowid(), NULL, NULL); - update t2 set k=k+10, val2=100+last_insert_rowid(); - update t2 set val3=1000+last_insert_rowid(); - end; - insert into v values (15); - select last_insert_rowid(); - } -} {0 13} - -# LIRID unchanged upon entry into instead of trigger -do_test lastinsert-4.2 { - catchsql { - select val1 from t2; - } -} {0 13} - -# LIRID changed properly by insert within context of instead of trigger -do_test lastinsert-4.3 { - catchsql { - select val2 from t2; - } -} {0 130} - -# LIRID unchanged by update within context of instead of trigger -do_test lastinsert-4.4 { - catchsql { - select val3 from t2; - } -} {0 1030} -} ;# ifcapable (view && trigger) - -# ---------------------------------------------------------------------------- -# 5.x - tests with before delete trigger - -# LIRID not changed after a delete on a table containing a before trigger -do_test lastinsert-5.1 { - catchsql { - drop trigger r1; -- This was not created if views are disabled. - } - catchsql { - delete from t2; - create trigger r1 before delete on t1 for each row begin - insert into t2 values (77, last_insert_rowid(), NULL, NULL); - update t2 set k=k+10, val2=100+last_insert_rowid(); - update t2 set val3=1000+last_insert_rowid(); - end; - delete from t1 where k=1; - select last_insert_rowid(); - } -} {0 13} - -# LIRID unchanged upon entry into delete trigger -do_test lastinsert-5.2 { - catchsql { - select val1 from t2; - } -} {0 13} - -# LIRID changed properly by insert within context of delete trigger -do_test lastinsert-5.3 { - catchsql { - select val2 from t2; - } -} {0 177} - -# LIRID unchanged by update within context of delete trigger -do_test lastinsert-5.4 { - catchsql { - select val3 from t2; - } -} {0 1077} - -# ---------------------------------------------------------------------------- -# 6.x - tests with instead of update trigger -# These tests may not run if either views or triggers are disabled. - -ifcapable {view && trigger} { -# LIRID not changed after an update on a view containing an instead of trigger -do_test lastinsert-6.1 { - catchsql { - delete from t2; - drop trigger r1; - create trigger r1 instead of update on v for each row begin - insert into t2 values (NEW.k*2, last_insert_rowid(), NULL, NULL); - update t2 set k=k+10, val2=100+last_insert_rowid(); - update t2 set val3=1000+last_insert_rowid(); - end; - update v set k=16 where k=14; - select last_insert_rowid(); - } -} {0 13} - -# LIRID unchanged upon entry into instead of trigger -do_test lastinsert-6.2 { - catchsql { - select val1 from t2; - } -} {0 13} - -# LIRID changed properly by insert within context of instead of trigger -do_test lastinsert-6.3 { - catchsql { - select val2 from t2; - } -} {0 132} - -# LIRID unchanged by update within context of instead of trigger -do_test lastinsert-6.4 { - catchsql { - select val3 from t2; - } -} {0 1032} -} ;# ifcapable (view && trigger) - -# ---------------------------------------------------------------------------- -# 7.x - complex tests with temporary tables and nested instead of triggers -# These do not run if views or triggers are disabled. - -ifcapable {trigger && view} { -do_test lastinsert-7.1 { - catchsql { - drop table t1; drop table t2; drop trigger r1; - create temp table t1 (k integer primary key); - create temp table t2 (k integer primary key); - create temp view v1 as select * from t1; - create temp view v2 as select * from t2; - create temp table rid (k integer primary key, rin, rout); - insert into rid values (1, NULL, NULL); - insert into rid values (2, NULL, NULL); - create temp trigger r1 instead of insert on v1 for each row begin - update rid set rin=last_insert_rowid() where k=1; - insert into t1 values (100+NEW.k); - insert into v2 values (100+last_insert_rowid()); - update rid set rout=last_insert_rowid() where k=1; - end; - create temp trigger r2 instead of insert on v2 for each row begin - update rid set rin=last_insert_rowid() where k=2; - insert into t2 values (1000+NEW.k); - update rid set rout=last_insert_rowid() where k=2; - end; - insert into t1 values (77); - select last_insert_rowid(); - } -} {0 77} - -do_test lastinsert-7.2 { - catchsql { - insert into v1 values (5); - select last_insert_rowid(); - } -} {0 77} - -do_test lastinsert-7.3 { - catchsql { - select rin from rid where k=1; - } -} {0 77} - -do_test lastinsert-7.4 { - catchsql { - select rout from rid where k=1; - } -} {0 105} - -do_test lastinsert-7.5 { - catchsql { - select rin from rid where k=2; - } -} {0 105} - -do_test lastinsert-7.6 { - catchsql { - select rout from rid where k=2; - } -} {0 1205} - -} ;# ifcapable (view && trigger) - -finish_test diff --git a/sqlite/test/laststmtchanges.test b/sqlite/test/laststmtchanges.test deleted file mode 100644 index ec4f7e2..0000000 --- a/sqlite/test/laststmtchanges.test +++ /dev/null @@ -1,270 +0,0 @@ -# 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. -# -#*********************************************************************** -# -# Tests to make sure that values returned by changes() and total_changes() -# are updated properly, especially inside triggers -# -# Note 1: changes() remains constant within a statement and only updates -# once the statement is finished (triggers count as part of -# statement). -# Note 2: changes() is changed within the context of a trigger much like -# last_insert_rowid() (see lastinsert.test), but is restored once -# the trigger exits. -# Note 3: changes() is not changed by a change to a view (since everything -# is done within instead of trigger context). -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# ---------------------------------------------------------------------------- -# 1.x - basic tests (no triggers) - -# changes() set properly after insert -do_test laststmtchanges-1.1 { - catchsql { - create table t0 (x); - insert into t0 values (1); - insert into t0 values (1); - insert into t0 values (2); - insert into t0 values (2); - insert into t0 values (1); - insert into t0 values (1); - insert into t0 values (1); - insert into t0 values (2); - select changes(), total_changes(); - } -} {0 {1 8}} - -# changes() set properly after update -do_test laststmtchanges-1.2 { - catchsql { - update t0 set x=3 where x=1; - select changes(), total_changes(); - } -} {0 {5 13}} - -# changes() unchanged within an update statement -do_test laststmtchanges-1.3 { - catchsql { - update t0 set x=x+changes() where x=3; - select count() from t0 where x=8; - } -} {0 5} - -# changes() set properly after update on table where no rows changed -do_test laststmtchanges-1.4 { - catchsql { - update t0 set x=77 where x=88; - select changes(); - } -} {0 0} - -# changes() set properly after delete from table -do_test laststmtchanges-1.5 { - catchsql { - delete from t0 where x=2; - select changes(); - } -} {0 3} - -# All remaining tests involve triggers. Skip them if triggers are not -# supported in this build. -# -ifcapable {!trigger} { - finish_test - return -} - - -# ---------------------------------------------------------------------------- -# 2.x - tests with after insert trigger - -# changes() changed properly after insert into table containing after trigger -do_test laststmtchanges-2.1 { - set ::tc [db total_changes] - catchsql { - create table t1 (k integer primary key); - create table t2 (k integer primary key, v1, v2); - create trigger r1 after insert on t1 for each row begin - insert into t2 values (NULL, changes(), NULL); - update t0 set x=x; - update t2 set v2=changes(); - end; - insert into t1 values (77); - select changes(); - } -} {0 1} - -# changes() unchanged upon entry into after insert trigger -do_test laststmtchanges-2.2 { - catchsql { - select v1 from t2; - } -} {0 3} - -# changes() changed properly by update within context of after insert trigger -do_test laststmtchanges-2.3 { - catchsql { - select v2 from t2; - } -} {0 5} - -# Total changes caused by firing the trigger above: -# -# 1 from "insert into t1 values(77)" + -# 1 from "insert into t2 values (NULL, changes(), NULL);" + -# 5 from "update t0 set x=x;" + -# 1 from "update t2 set v2=changes();" -# -do_test laststmtchanges-2.4 { - expr [db total_changes] - $::tc -} {8} - -# ---------------------------------------------------------------------------- -# 3.x - tests with after update trigger - -# changes() changed properly after update into table containing after trigger -do_test laststmtchanges-3.1 { - catchsql { - drop trigger r1; - delete from t2; delete from t2; - create trigger r1 after update on t1 for each row begin - insert into t2 values (NULL, changes(), NULL); - delete from t0 where oid=1 or oid=2; - update t2 set v2=changes(); - end; - update t1 set k=k; - select changes(); - } -} {0 1} - -# changes() unchanged upon entry into after update trigger -do_test laststmtchanges-3.2 { - catchsql { - select v1 from t2; - } -} {0 0} - -# changes() changed properly by delete within context of after update trigger -do_test laststmtchanges-3.3 { - catchsql { - select v2 from t2; - } -} {0 2} - -# ---------------------------------------------------------------------------- -# 4.x - tests with before delete trigger - -# changes() changed properly on delete from table containing before trigger -do_test laststmtchanges-4.1 { - catchsql { - drop trigger r1; - delete from t2; delete from t2; - create trigger r1 before delete on t1 for each row begin - insert into t2 values (NULL, changes(), NULL); - insert into t0 values (5); - update t2 set v2=changes(); - end; - delete from t1; - select changes(); - } -} {0 1} - -# changes() unchanged upon entry into before delete trigger -do_test laststmtchanges-4.2 { - catchsql { - select v1 from t2; - } -} {0 0} - -# changes() changed properly by insert within context of before delete trigger -do_test laststmtchanges-4.3 { - catchsql { - select v2 from t2; - } -} {0 1} - -# ---------------------------------------------------------------------------- -# 5.x - complex tests with temporary tables and nested instead of triggers -# These tests cannot run if the library does not have view support enabled. - -ifcapable view { - -do_test laststmtchanges-5.1 { - catchsql { - drop table t0; drop table t1; drop table t2; - create temp table t0(x); - create temp table t1 (k integer primary key); - create temp table t2 (k integer primary key); - create temp view v1 as select * from t1; - create temp view v2 as select * from t2; - create temp table n1 (k integer primary key, n); - create temp table n2 (k integer primary key, n); - insert into t0 values (1); - insert into t0 values (2); - insert into t0 values (1); - insert into t0 values (1); - insert into t0 values (1); - insert into t0 values (2); - insert into t0 values (2); - insert into t0 values (1); - create temp trigger r1 instead of insert on v1 for each row begin - insert into n1 values (NULL, changes()); - update t0 set x=x*10 where x=1; - insert into n1 values (NULL, changes()); - insert into t1 values (NEW.k); - insert into n1 values (NULL, changes()); - update t0 set x=x*10 where x=0; - insert into v2 values (100+NEW.k); - insert into n1 values (NULL, changes()); - end; - create temp trigger r2 instead of insert on v2 for each row begin - insert into n2 values (NULL, changes()); - insert into t2 values (1000+NEW.k); - insert into n2 values (NULL, changes()); - update t0 set x=x*100 where x=0; - insert into n2 values (NULL, changes()); - delete from t0 where x=2; - insert into n2 values (NULL, changes()); - end; - insert into t1 values (77); - select changes(); - } -} {0 1} - -do_test laststmtchanges-5.2 { - catchsql { - delete from t1 where k=88; - select changes(); - } -} {0 0} - -do_test laststmtchanges-5.3 { - catchsql { - insert into v1 values (5); - select changes(); - } -} {0 0} - -do_test laststmtchanges-5.4 { - catchsql { - select n from n1; - } -} {0 {0 5 1 0}} - -do_test laststmtchanges-5.5 { - catchsql { - select n from n2; - } -} {0 {0 1 0 3}} - -} ;# ifcapable view - -finish_test diff --git a/sqlite/test/limit.test b/sqlite/test/limit.test deleted file mode 100644 index 77b4bc1..0000000 --- a/sqlite/test/limit.test +++ /dev/null @@ -1,428 +0,0 @@ -# 2001 November 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 implements regression tests for SQLite library. The -# focus of this file is testing the LIMIT ... OFFSET ... clause -# of SELECT statements. -# -# $Id: limit.test,v 1.24 2005/02/05 12:48:49 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Build some test data -# -execsql { - CREATE TABLE t1(x int, y int); - BEGIN; -} -for {set i 1} {$i<=32} {incr i} { - for {set j 0} {pow(2,$j)<$i} {incr j} {} - execsql "INSERT INTO t1 VALUES([expr {32-$i}],[expr {10-$j}])" -} -execsql { - COMMIT; -} - -do_test limit-1.0 { - execsql {SELECT count(*) FROM t1} -} {32} -do_test limit-1.1 { - execsql {SELECT count(*) FROM t1 LIMIT 5} -} {32} -do_test limit-1.2.1 { - execsql {SELECT x FROM t1 ORDER BY x LIMIT 5} -} {0 1 2 3 4} -do_test limit-1.2.2 { - execsql {SELECT x FROM t1 ORDER BY x LIMIT 5 OFFSET 2} -} {2 3 4 5 6} -do_test limit-1.2.3 { - execsql {SELECT x FROM t1 ORDER BY x LIMIT 2, 5} -} {2 3 4 5 6} -do_test limit-1.3 { - execsql {SELECT x FROM t1 ORDER BY x LIMIT 5 OFFSET 5} -} {5 6 7 8 9} -do_test limit-1.4.1 { - execsql {SELECT x FROM t1 ORDER BY x LIMIT 50 OFFSET 30} -} {30 31} -do_test limit-1.4.2 { - execsql {SELECT x FROM t1 ORDER BY x LIMIT 30, 50} -} {30 31} -do_test limit-1.5 { - execsql {SELECT x FROM t1 ORDER BY x LIMIT 50 OFFSET 50} -} {} -do_test limit-1.6 { - execsql {SELECT * FROM t1 AS a, t1 AS b ORDER BY a.x, b.x LIMIT 5} -} {0 5 0 5 0 5 1 5 0 5 2 5 0 5 3 5 0 5 4 5} -do_test limit-1.7 { - execsql {SELECT * FROM t1 AS a, t1 AS b ORDER BY a.x, b.x LIMIT 5 OFFSET 32} -} {1 5 0 5 1 5 1 5 1 5 2 5 1 5 3 5 1 5 4 5} - -ifcapable {view && subquery} { - do_test limit-2.1 { - execsql { - CREATE VIEW v1 AS SELECT * FROM t1 LIMIT 2; - SELECT count(*) FROM (SELECT * FROM v1); - } - } 2 -} ;# ifcapable view -do_test limit-2.2 { - execsql { - CREATE TABLE t2 AS SELECT * FROM t1 LIMIT 2; - SELECT count(*) FROM t2; - } -} 2 -ifcapable subquery { - do_test limit-2.3 { - execsql { - SELECT count(*) FROM t1 WHERE rowid IN (SELECT rowid FROM t1 LIMIT 2); - } - } 2 -} - -ifcapable subquery { - do_test limit-3.1 { - execsql { - SELECT z FROM (SELECT y*10+x AS z FROM t1 ORDER BY x LIMIT 10) - ORDER BY z LIMIT 5; - } - } {50 51 52 53 54} -} - -do_test limit-4.1 { - ifcapable subquery { - execsql { - BEGIN; - CREATE TABLE t3(x); - INSERT INTO t3 SELECT x FROM t1 ORDER BY x LIMIT 10 OFFSET 1; - INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3; - INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3; - INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3; - INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3; - INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3; - INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3; - INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3; - INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3; - INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3; - INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3; - END; - SELECT count(*) FROM t3; - } - } else { - execsql { - BEGIN; - CREATE TABLE t3(x); - INSERT INTO t3 SELECT x FROM t1 ORDER BY x LIMIT 10 OFFSET 1; - } - for {set i 0} {$i<10} {incr i} { - set max_x_t3 [execsql {SELECT max(x) FROM t3}] - execsql "INSERT INTO t3 SELECT x+$max_x_t3 FROM t3;" - } - execsql { - END; - SELECT count(*) FROM t3; - } - } -} {10240} -do_test limit-4.2 { - execsql { - SELECT x FROM t3 LIMIT 2 OFFSET 10000 - } -} {10001 10002} -do_test limit-4.3 { - execsql { - CREATE TABLE t4 AS SELECT x, - 'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x || - 'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x || - 'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x || - 'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x || - 'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x AS y - FROM t3 LIMIT 1000; - SELECT x FROM t4 ORDER BY y DESC LIMIT 1 OFFSET 999; - } -} {1000} - -do_test limit-5.1 { - execsql { - CREATE TABLE t5(x,y); - INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x BETWEEN 10 AND 15 - ORDER BY x LIMIT 2; - SELECT * FROM t5 ORDER BY x; - } -} {5 15 6 16} -do_test limit-5.2 { - execsql { - DELETE FROM t5; - INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x BETWEEN 10 AND 15 - ORDER BY x DESC LIMIT 2; - SELECT * FROM t5 ORDER BY x; - } -} {9 19 10 20} -do_test limit-5.3 { - execsql { - DELETE FROM t5; - INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x ORDER BY x DESC LIMIT 31; - SELECT * FROM t5 ORDER BY x LIMIT 2; - } -} {-4 6 -3 7} -do_test limit-5.4 { - execsql { - SELECT * FROM t5 ORDER BY x DESC, y DESC LIMIT 2; - } -} {21 41 21 39} -do_test limit-5.5 { - execsql { - DELETE FROM t5; - INSERT INTO t5 SELECT a.x*100+b.x, a.y*100+b.y FROM t1 AS a, t1 AS b - ORDER BY 1, 2 LIMIT 1000; - SELECT count(*), sum(x), sum(y), min(x), max(x), min(y), max(y) FROM t5; - } -} {1000 1528204.0 593161.0 0 3107 505 1005} - -# There is some contraversy about whether LIMIT 0 should be the same as -# no limit at all or if LIMIT 0 should result in zero output rows. -# -do_test limit-6.1 { - execsql { - BEGIN; - CREATE TABLE t6(a); - INSERT INTO t6 VALUES(1); - INSERT INTO t6 VALUES(2); - INSERT INTO t6 SELECT a+2 FROM t6; - COMMIT; - SELECT * FROM t6; - } -} {1 2 3 4} -do_test limit-6.2 { - execsql { - SELECT * FROM t6 LIMIT -1 OFFSET -1; - } -} {1 2 3 4} -do_test limit-6.3 { - execsql { - SELECT * FROM t6 LIMIT 2 OFFSET -123; - } -} {1 2} -do_test limit-6.4 { - execsql { - SELECT * FROM t6 LIMIT -432 OFFSET 2; - } -} {3 4} -do_test limit-6.5 { - execsql { - SELECT * FROM t6 LIMIT -1 - } -} {1 2 3 4} -do_test limit-6.6 { - execsql { - SELECT * FROM t6 LIMIT -1 OFFSET 1 - } -} {2 3 4} -do_test limit-6.7 { - execsql { - SELECT * FROM t6 LIMIT 0 - } -} {} -do_test limit-6.8 { - execsql { - SELECT * FROM t6 LIMIT 0 OFFSET 1 - } -} {} - -# Make sure LIMIT works well with compound SELECT statements. -# Ticket #393 -# -ifcapable compound { -do_test limit-7.1.1 { - catchsql { - SELECT x FROM t2 LIMIT 5 UNION ALL SELECT a FROM t6; - } -} {1 {LIMIT clause should come after UNION ALL not before}} -do_test limit-7.1.2 { - catchsql { - SELECT x FROM t2 LIMIT 5 UNION SELECT a FROM t6; - } -} {1 {LIMIT clause should come after UNION not before}} -do_test limit-7.1.3 { - catchsql { - SELECT x FROM t2 LIMIT 5 EXCEPT SELECT a FROM t6 LIMIT 3; - } -} {1 {LIMIT clause should come after EXCEPT not before}} -do_test limit-7.1.4 { - catchsql { - SELECT x FROM t2 LIMIT 0,5 INTERSECT SELECT a FROM t6; - } -} {1 {LIMIT clause should come after INTERSECT not before}} -do_test limit-7.2 { - execsql { - SELECT x FROM t2 UNION ALL SELECT a FROM t6 LIMIT 5; - } -} {31 30 1 2 3} -do_test limit-7.3 { - execsql { - SELECT x FROM t2 UNION ALL SELECT a FROM t6 LIMIT 3 OFFSET 1; - } -} {30 1 2} -do_test limit-7.4 { - execsql { - SELECT x FROM t2 UNION ALL SELECT a FROM t6 ORDER BY 1 LIMIT 3 OFFSET 1; - } -} {2 3 4} -do_test limit-7.5 { - execsql { - SELECT x FROM t2 UNION SELECT x+2 FROM t2 LIMIT 2 OFFSET 1; - } -} {31 32} -do_test limit-7.6 { - execsql { - SELECT x FROM t2 UNION SELECT x+2 FROM t2 ORDER BY 1 DESC LIMIT 2 OFFSET 1; - } -} {32 31} -do_test limit-7.7 { - execsql { - SELECT a+9 FROM t6 EXCEPT SELECT y FROM t2 LIMIT 2; - } -} {11 12} -do_test limit-7.8 { - execsql { - SELECT a+9 FROM t6 EXCEPT SELECT y FROM t2 ORDER BY 1 DESC LIMIT 2; - } -} {13 12} -do_test limit-7.9 { - execsql { - SELECT a+26 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1; - } -} {30} -do_test limit-7.10 { - execsql { - SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1; - } -} {30} -do_test limit-7.11 { - execsql { - SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1 OFFSET 1; - } -} {31} -do_test limit-7.12 { - execsql { - SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2 - ORDER BY 1 DESC LIMIT 1 OFFSET 1; - } -} {30} -} ;# ifcapable compound - -# Tests for limit in conjunction with distinct. The distinct should -# occur before both the limit and the offset. Ticket #749. -# -do_test limit-8.1 { - execsql { - SELECT DISTINCT round(x/100) FROM t3 LIMIT 5; - } -} {0 1 2 3 4} -do_test limit-8.2 { - execsql { - SELECT DISTINCT round(x/100) FROM t3 LIMIT 5 OFFSET 5; - } -} {5 6 7 8 9} -do_test limit-8.3 { - execsql { - SELECT DISTINCT round(x/100) FROM t3 LIMIT 5 OFFSET 25; - } -} {25 26 27 28 29} - -# Make sure limits on multiple subqueries work correctly. -# Ticket #1035 -# -ifcapable subquery { - do_test limit-9.1 { - execsql { - SELECT * FROM (SELECT * FROM t6 LIMIT 3); - } - } {1 2 3} -} -do_test limit-9.2.1 { - execsql { - CREATE TABLE t7 AS SELECT * FROM t6; - } -} {} -ifcapable subquery { - do_test limit-9.2.2 { - execsql { - SELECT * FROM (SELECT * FROM t7 LIMIT 3); - } - } {1 2 3} -} -ifcapable compound { - ifcapable subquery { - do_test limit-9.3 { - execsql { - SELECT * FROM (SELECT * FROM t6 LIMIT 3) - UNION - SELECT * FROM (SELECT * FROM t7 LIMIT 3) - ORDER BY 1 - } - } {1 2 3} - do_test limit-9.4 { - execsql { - SELECT * FROM (SELECT * FROM t6 LIMIT 3) - UNION - SELECT * FROM (SELECT * FROM t7 LIMIT 3) - ORDER BY 1 - LIMIT 2 - } - } {1 2} - } - do_test limit-9.5 { - catchsql { - SELECT * FROM t6 LIMIT 3 - UNION - SELECT * FROM t7 LIMIT 3 - } - } {1 {LIMIT clause should come after UNION not before}} -} - -# Test LIMIT and OFFSET using SQL variables. -do_test limit-10.1 { - set limit 10 - db eval { - SELECT x FROM t1 LIMIT $limit; - } -} {31 30 29 28 27 26 25 24 23 22} -do_test limit-10.2 { - set limit 5 - set offset 5 - db eval { - SELECT x FROM t1 LIMIT $limit OFFSET $offset; - } -} {26 25 24 23 22} -do_test limit-10.3 { - set limit -1 - db eval { - SELECT x FROM t1 WHERE x<10 LIMIT $limit; - } -} {9 8 7 6 5 4 3 2 1 0} -do_test limit-10.4 { - set limit 1.5 - set rc [catch { - db eval { - SELECT x FROM t1 WHERE x<10 LIMIT $limit; - } } msg] - list $rc $msg -} {1 {datatype mismatch}} -do_test limit-10.5 { - set limit "hello world" - set rc [catch { - db eval { - SELECT x FROM t1 WHERE x<10 LIMIT $limit; - } } msg] - list $rc $msg -} {1 {datatype mismatch}} - -finish_test diff --git a/sqlite/test/lock.test b/sqlite/test/lock.test deleted file mode 100644 index d56a05c..0000000 --- a/sqlite/test/lock.test +++ /dev/null @@ -1,321 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this script is database locks. -# -# $Id: lock.test,v 1.30 2005/01/12 12:44:04 danielk1977 Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Create an alternative connection to the database -# -do_test lock-1.0 { - sqlite3 db2 ./test.db - set dummy {} -} {} -do_test lock-1.1 { - execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} -} {} -do_test lock-1.2 { - execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} db2 -} {} -do_test lock-1.3 { - execsql {CREATE TABLE t1(a int, b int)} - execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} -} {t1} -do_test lock-1.5 { - catchsql { - SELECT name FROM sqlite_master WHERE type='table' ORDER BY name - } db2 -} {0 t1} - -do_test lock-1.6 { - execsql {INSERT INTO t1 VALUES(1,2)} - execsql {SELECT * FROM t1} -} {1 2} -# Update: The schema is now brought up to date by test lock-1.5. -# do_test lock-1.7.1 { -# catchsql {SELECT * FROM t1} db2 -# } {1 {no such table: t1}} -do_test lock-1.7.2 { - catchsql {SELECT * FROM t1} db2 -} {0 {1 2}} -do_test lock-1.8 { - execsql {UPDATE t1 SET a=b, b=a} db2 - execsql {SELECT * FROM t1} db2 -} {2 1} -do_test lock-1.9 { - execsql {SELECT * FROM t1} -} {2 1} -do_test lock-1.10 { - execsql {BEGIN TRANSACTION} - execsql {UPDATE t1 SET a = 0 WHERE 0} - execsql {SELECT * FROM t1} -} {2 1} -do_test lock-1.11 { - catchsql {SELECT * FROM t1} db2 -} {0 {2 1}} -do_test lock-1.12 { - execsql {ROLLBACK} - catchsql {SELECT * FROM t1} -} {0 {2 1}} - -do_test lock-1.13 { - execsql {CREATE TABLE t2(x int, y int)} - execsql {INSERT INTO t2 VALUES(8,9)} - execsql {SELECT * FROM t2} -} {8 9} -do_test lock-1.14.1 { - catchsql {SELECT * FROM t2} db2 -} {1 {no such table: t2}} -do_test lock-1.14.2 { - catchsql {SELECT * FROM t1} db2 -} {0 {2 1}} -do_test lock-1.15 { - catchsql {SELECT * FROM t2} db2 -} {0 {8 9}} - -do_test lock-1.16 { - db eval {SELECT * FROM t1} qv { - set x [db eval {SELECT * FROM t1}] - } - set x -} {2 1} -do_test lock-1.17 { - db eval {SELECT * FROM t1} qv { - set x [db eval {SELECT * FROM t2}] - } - set x -} {8 9} - -# You cannot UPDATE a table from within the callback of a SELECT -# on that same table because the SELECT has the table locked. -do_test lock-1.18 { - db eval {SELECT * FROM t1} qv { - set r [catch {db eval {UPDATE t1 SET a=b, b=a}} msg] - lappend r $msg - } - set r -} {1 {database table is locked}} - -# But you can UPDATE a different table from the one that is used in -# the SELECT. -# -do_test lock-1.19 { - db eval {SELECT * FROM t1} qv { - set r [catch {db eval {UPDATE t2 SET x=y, y=x}} msg] - lappend r $msg - } - set r -} {0 {}} -do_test lock-1.20 { - execsql {SELECT * FROM t2} -} {9 8} - -# It is possible to do a SELECT of the same table within the -# callback of another SELECT on that same table because two -# or more read-only cursors can be open at once. -# -do_test lock-1.21 { - db eval {SELECT * FROM t1} qv { - set r [catch {db eval {SELECT a FROM t1}} msg] - lappend r $msg - } - set r -} {0 2} - -# Under UNIX you can do two SELECTs at once with different database -# connections, because UNIX supports reader/writer locks. Under windows, -# this is not possible. -# -if {$::tcl_platform(platform)=="unix"} { - do_test lock-1.22 { - db eval {SELECT * FROM t1} qv { - set r [catch {db2 eval {SELECT a FROM t1}} msg] - lappend r $msg - } - set r - } {0 2} -} -integrity_check lock-1.23 - -# If one thread has a transaction another thread cannot start -# a transaction. -> Not true in version 3.0. But if one thread -# as a RESERVED lock another thread cannot acquire one. -# -do_test lock-2.1 { - execsql {BEGIN TRANSACTION} - execsql {UPDATE t1 SET a = 0 WHERE 0} - execsql {BEGIN TRANSACTION} db2 - set r [catch {execsql {UPDATE t1 SET a = 0 WHERE 0} db2} msg] - execsql {ROLLBACK} db2 - lappend r $msg -} {1 {database is locked}} - -# A thread can read when another has a RESERVED lock. -# -do_test lock-2.2 { - catchsql {SELECT * FROM t2} db2 -} {0 {9 8}} - -# If the other thread (the one that does not hold the transaction with -# a RESERVED lock) tries to get a RESERVED lock, we do not get a busy callback. -# -do_test lock-2.3 { - proc callback {count} { - set ::callback_value $count - break - } - set ::callback_value {} - db2 busy callback - set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg] - lappend r $msg - lappend r $::callback_value -} {1 {database is locked} {}} -do_test lock-2.4 { - proc callback {count} { - lappend ::callback_value $count - if {$count>4} break - } - set ::callback_value {} - db2 busy callback - set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg] - lappend r $msg - lappend r $::callback_value -} {1 {database is locked} {}} -do_test lock-2.5 { - proc callback {count} { - lappend ::callback_value $count - if {$count>4} break - } - set ::callback_value {} - db2 busy callback - set r [catch {execsql {SELECT * FROM t1} db2} msg] - lappend r $msg - lappend r $::callback_value -} {0 {2 1} {}} -execsql {ROLLBACK} - -# Test the built-in busy timeout handler -# -do_test lock-2.8 { - db2 timeout 400 - execsql BEGIN - execsql {UPDATE t1 SET a = 0 WHERE 0} - catchsql {BEGIN EXCLUSIVE;} db2 -} {1 {database is locked}} -do_test lock-2.9 { - db2 timeout 0 - execsql COMMIT -} {} -integrity_check lock-2.10 - -# Try to start two transactions in a row -# -do_test lock-3.1 { - execsql {BEGIN TRANSACTION} - set r [catch {execsql {BEGIN TRANSACTION}} msg] - execsql {ROLLBACK} - lappend r $msg -} {1 {cannot start a transaction within a transaction}} -integrity_check lock-3.2 - -# Make sure the busy handler and error messages work when -# opening a new pointer to the database while another pointer -# has the database locked. -# -do_test lock-4.1 { - db2 close - catch {db eval ROLLBACK} - db eval BEGIN - db eval {UPDATE t1 SET a=0 WHERE 0} - sqlite3 db2 ./test.db - catchsql {UPDATE t1 SET a=0} db2 -} {1 {database is locked}} -do_test lock-4.2 { - set ::callback_value {} - set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg] - lappend rc $msg $::callback_value -} {1 {database is locked} {}} -do_test lock-4.3 { - proc callback {count} { - lappend ::callback_value $count - if {$count>4} break - } - db2 busy callback - set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg] - lappend rc $msg $::callback_value -} {1 {database is locked} {}} -execsql {ROLLBACK} - -# When one thread is writing, other threads cannot read. Except if the -# writing thread is writing to its temporary tables, the other threads -# can still read. -> Not so in 3.0. One thread can read while another -# holds a RESERVED lock. -# -proc tx_exec {sql} { - db2 eval $sql -} -do_test lock-5.1 { - execsql { - SELECT * FROM t1 - } -} {2 1} -do_test lock-5.2 { - db function tx_exec tx_exec - catchsql { - INSERT INTO t1(a,b) SELECT 3, tx_exec('SELECT y FROM t2 LIMIT 1'); - } -} {0 {}} -do_test lock-5.3 { - execsql { - CREATE TEMP TABLE t3(x); - SELECT * FROM t3; - } -} {} -do_test lock-5.4 { - catchsql { - INSERT INTO t3 SELECT tx_exec('SELECT y FROM t2 LIMIT 1'); - } -} {0 {}} -do_test lock-5.5 { - execsql { - SELECT * FROM t3; - } -} {8} -do_test lock-5.6 { - catchsql { - UPDATE t1 SET a=tx_exec('SELECT x FROM t2'); - } -} {0 {}} -do_test lock-5.7 { - execsql { - SELECT * FROM t1; - } -} {9 1 9 8} -do_test lock-5.8 { - catchsql { - UPDATE t3 SET x=tx_exec('SELECT x FROM t2'); - } -} {0 {}} -do_test lock-5.9 { - execsql { - SELECT * FROM t3; - } -} {9} - -do_test lock-999.1 { - rename db2 {} -} {} - -finish_test diff --git a/sqlite/test/lock2.test b/sqlite/test/lock2.test deleted file mode 100644 index 7da6ad1..0000000 --- a/sqlite/test/lock2.test +++ /dev/null @@ -1,159 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this script is database locks between competing processes. -# -# $Id: lock2.test,v 1.4 2004/11/10 15:27:38 danielk1977 Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Launch another testfixture process to be controlled by this one. A -# channel name is returned that may be passed as the first argument to proc -# 'testfixture' to execute a command. The child testfixture process is shut -# down by closing the channel. -proc launch_testfixture {} { - set chan [open "|[file join . testfixture] tf_main.tcl" r+] - fconfigure $chan -buffering line - return $chan -} - -# Execute a command in a child testfixture process, connected by two-way -# channel $chan. Return the result of the command, or an error message. -proc testfixture {chan cmd} { - puts $chan $cmd - puts $chan OVER - set r "" - while { 1 } { - set line [gets $chan] - if { $line == "OVER" } { - return $r - } - append r $line - } -} - -# Write the main loop for the child testfixture processes into file -# tf_main.tcl. The parent (this script) interacts with the child processes -# via a two way pipe. The parent writes a script to the stdin of the child -# process, followed by the word "OVER" on a line of it's own. The child -# process evaluates the script and writes the results to stdout, followed -# by an "OVER" of its own. -set f [open tf_main.tcl w] -puts $f { - set l [open log w] - set script "" - while {![eof stdin]} { - flush stdout - set line [gets stdin] - puts $l "READ $line" - if { $line == "OVER" } { - catch {eval $script} result - puts $result - puts $l "WRITE $result" - puts OVER - puts $l "WRITE OVER" - flush stdout - set script "" - } else { - append script $line - append script " ; " - } - } - close $l -} -close $f - -# Simple locking test case: -# -# lock2-1.1: Connect a second process to the database. -# lock2-1.2: Establish a RESERVED lock with this process. -# lock2-1.3: Get a SHARED lock with the second process. -# lock2-1.4: Try for a RESERVED lock with process 2. This fails. -# lock2-1.5: Try to upgrade the first process to EXCLUSIVE, this fails so -# it gets PENDING. -# lock2-1.6: Release the SHARED lock held by the second process. -# lock2-1.7: Attempt to reaquire a SHARED lock with the second process. -# this fails due to the PENDING lock. -# lock2-1.8: Ensure the first process can now upgrade to EXCLUSIVE. -# -do_test lock2-1.1 { - set ::tf1 [launch_testfixture] - testfixture $::tf1 { - sqlite3 db test.db -key xyzzy - db eval {select * from sqlite_master} - } -} {} -do_test lock2-1.2 { - execsql { - BEGIN; - CREATE TABLE abc(a, b, c); - } -} {} -do_test lock2-1.3 { - testfixture $::tf1 { - db eval { - BEGIN; - SELECT * FROM sqlite_master; - } - } -} {} -do_test lock2-1.4 { - testfixture $::tf1 { - db eval { - CREATE TABLE def(d, e, f) - } - } -} {database is locked} -do_test lock2-1.5 { - catchsql { - COMMIT; - } -} {1 {database is locked}} -do_test lock2-1.6 { - testfixture $::tf1 { - db eval { - SELECT * FROM sqlite_master; - COMMIT; - } - } -} {} -do_test lock2-1.7 { - testfixture $::tf1 { - db eval { - BEGIN; - SELECT * FROM sqlite_master; - } - } -} {database is locked} -do_test lock2-1.8 { - catchsql { - COMMIT; - } -} {0 {}} -do_test lock2-1.9 { - execsql { - SELECT * FROM sqlite_master; - } -} "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}" -do_test lock2-1.10 { - testfixture $::tf1 { - db eval { - SELECT * FROM sqlite_master; - } - } -} "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}" - -catch {testfixture $::tf1 {db close}} -catch {close $::tf1} - -finish_test diff --git a/sqlite/test/main.test b/sqlite/test/main.test deleted file mode 100644 index 26f8381..0000000 --- a/sqlite/test/main.test +++ /dev/null @@ -1,303 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is exercising the code in main.c. -# -# $Id: main.test,v 1.19 2005/01/11 17:46:42 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Tests of the sqlite_complete() function. -# -do_test main-1.1 { - db complete {This is a test} -} {0} -do_test main-1.2 { - db complete { - } -} {1} -do_test main-1.3 { - db complete { - -- a comment ; - } -} {1} -do_test main-1.4 { - db complete { - -- a comment ; - ; - } -} {1} -do_test main-1.5 { - db complete {DROP TABLE 'xyz;} -} {0} -do_test main-1.6 { - db complete {DROP TABLE 'xyz';} -} {1} -do_test main-1.7 { - db complete {DROP TABLE "xyz;} -} {0} -do_test main-1.8 { - db complete {DROP TABLE "xyz';} -} {0} -do_test main-1.9 { - db complete {DROP TABLE "xyz";} -} {1} -do_test main-1.10 { - db complete {DROP TABLE xyz; hi} -} {0} -do_test main-1.11 { - db complete {DROP TABLE xyz; } -} {1} -do_test main-1.12 { - db complete {DROP TABLE xyz; -- hi } -} {1} -do_test main-1.13 { - db complete {DROP TABLE xyz; -- hi - } -} {1} -do_test main-1.14 { - db complete {SELECT a-b FROM t1; } -} {1} -do_test main-1.15 { - db complete {SELECT a/e FROM t1 } -} {0} -do_test main-1.16 { - db complete { - CREATE TABLE abc(x,y); - } -} {1} -ifcapable {trigger} { - do_test main-1.17 { - db complete { - CREATE TRIGGER xyz AFTER DELETE abc BEGIN UPDATE pqr; - } - } {0} - do_test main-1.18 { - db complete { - CREATE TRIGGER xyz AFTER DELETE abc BEGIN UPDATE pqr; END; - } - } {1} - do_test main-1.19 { - db complete { - CREATE TRIGGER xyz AFTER DELETE abc BEGIN - UPDATE pqr; - unknown command; - } - } {0} - do_test main-1.20 { - db complete { - CREATE TRIGGER xyz AFTER DELETE backend BEGIN - UPDATE pqr; - } - } {0} - do_test main-1.21 { - db complete { - CREATE TRIGGER xyz AFTER DELETE end BEGIN - SELECT a, b FROM end; - } - } {0} - do_test main-1.22 { - db complete { - CREATE TRIGGER xyz AFTER DELETE end BEGIN - SELECT a, b FROM end; - END; - } - } {1} - do_test main-1.23 { - db complete { - CREATE TRIGGER xyz AFTER DELETE end BEGIN - SELECT a, b FROM end; - END; - SELECT a, b FROM end; - } - } {1} - do_test main-1.24 { - db complete { - CREATE TRIGGER xyz AFTER DELETE [;end;] BEGIN - UPDATE pqr; - } - } {0} - do_test main-1.25 { - db complete { - CREATE TRIGGER xyz AFTER DELETE backend BEGIN - UPDATE pqr SET a=[;end;];;; - } - } {0} - do_test main-1.26 { - db complete { - CREATE -- a comment - TRIGGER xyz AFTER DELETE backend BEGIN - UPDATE pqr SET a=5; - } - } {0} - do_test main-1.27.1 { - db complete { - CREATE -- a comment - TRIGGERX xyz AFTER DELETE backend BEGIN - UPDATE pqr SET a=5; - } - } {1} - do_test main-1.27.2 { - db complete { - CREATE/**/TRIGGER xyz AFTER DELETE backend BEGIN - UPDATE pqr SET a=5; - } - } {0} - ifcapable {explain} { - do_test main-1.27.3 { - db complete { - /* */ EXPLAIN -- A comment - CREATE/**/TRIGGER xyz AFTER DELETE backend BEGIN - UPDATE pqr SET a=5; - } - } {0} - } - do_test main-1.27.4 { - db complete { - BOGUS token - CREATE TRIGGER xyz AFTER DELETE backend BEGIN - UPDATE pqr SET a=5; - } - } {1} - ifcapable {explain} { - do_test main-1.27.5 { - db complete { - EXPLAIN - CREATE TEMP TRIGGER xyz AFTER DELETE backend BEGIN - UPDATE pqr SET a=5; - } - } {0} - } - do_test main-1.28 { - db complete { - CREATE TEMPORARY TRIGGER xyz AFTER DELETE backend BEGIN - UPDATE pqr SET a=5; - } - } {0} - do_test main-1.29 { - db complete { - CREATE TRIGGER xyz AFTER DELETE backend BEGIN - UPDATE pqr SET a=5; - EXPLAIN select * from xyz; - } - } {0} -} -do_test main-1.30 { - db complete { - CREATE TABLE /* In comment ; */ - } -} {0} -do_test main-1.31 { - db complete { - CREATE TABLE /* In comment ; */ hi; - } -} {1} -do_test main-1.31 { - db complete { - CREATE TABLE /* In comment ; */; - } -} {1} -do_test main-1.32 { - db complete { - stuff; - /* - CREATE TABLE - multiple lines - of text - */ - } -} {1} -do_test main-1.33 { - db complete { - /* - CREATE TABLE - multiple lines - of text; - } -} {0} -do_test main-1.34 { - db complete { - /* - CREATE TABLE - multiple lines "*/ - of text; - } -} {1} -do_test main-1.35 { - db complete {hi /**/ there;} -} {1} -do_test main-1.36 { - db complete {hi there/***/;} -} {1} - - -# Try to open a database with a corrupt database file. -# -do_test main-2.0 { - catch {db close} - file delete -force test.db - set fd [open test.db w] - puts $fd hi! - close $fd - set v [catch {sqlite3 db test.db} msg] - if {$v} {lappend v $msg} {lappend v {}} -} {0 {}} - -# Here are some tests for tokenize.c. -# -do_test main-3.1 { - catch {db close} - foreach f [glob -nocomplain testdb/*] {file delete -force $f} - file delete -force testdb - sqlite3 db testdb - set v [catch {execsql {SELECT * from T1 where x!!5}} msg] - lappend v $msg -} {1 {unrecognized token: "!!"}} -do_test main-3.2 { - catch {db close} - foreach f [glob -nocomplain testdb/*] {file delete -force $f} - file delete -force testdb - sqlite3 db testdb - set v [catch {execsql {SELECT * from T1 where @x}} msg] - lappend v $msg -} {1 {unrecognized token: "@"}} - -do_test main-3.3 { - catch {db close} - foreach f [glob -nocomplain testdb/*] {file delete -force $f} - file delete -force testdb - sqlite3 db testdb - execsql { - create table T1(X REAL); /* C-style comments allowed */ - insert into T1 values(0.5); - insert into T1 values(0.5e2); - insert into T1 values(0.5e-002); - insert into T1 values(5e-002); - insert into T1 values(-5.0e-2); - insert into T1 values(-5.1e-2); - insert into T1 values(0.5e2); - insert into T1 values(0.5E+02); - insert into T1 values(5E+02); - insert into T1 values(5.0E+03); - select x*10 from T1 order by x*5; - } -} {-0.51 -0.5 0.05 0.5 5.0 500.0 500.0 500.0 5000.0 50000.0} -do_test main-3.4 { - set v [catch {execsql {create bogus}} msg] - lappend v $msg -} {1 {near "bogus": syntax error}} -do_test main-3.5 { - set v [catch {execsql {create}} msg] - lappend v $msg -} {1 {near "create": syntax error}} - -finish_test diff --git a/sqlite/test/malloc.test b/sqlite/test/malloc.test deleted file mode 100644 index 63652b2..0000000 --- a/sqlite/test/malloc.test +++ /dev/null @@ -1,386 +0,0 @@ -# 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 attempts to check the library in an out-of-memory situation. -# When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special -# command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This -# special feature is used to see what happens in the library if a malloc -# were to really fail due to an out-of-memory situation. -# -# $Id: malloc.test,v 1.22 2005/01/22 03:39:39 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Only run these tests if memory debugging is turned on. -# -if {[info command sqlite_malloc_stat]==""} { - puts "Skipping malloc tests: not compiled with -DSQLITE_DEBUG..." - finish_test - return -} - -# Usage: do_malloc_test -# -# The first argument, , is an integer used to name the -# tests executed by this proc. Options are as follows: -# -# -tclprep TCL script to run to prepare test. -# -sqlprep SQL script to run to prepare test. -# -tclbody TCL script to run with malloc failure simulation. -# -sqlbody TCL script to run with malloc failure simulation. -# -cleanup TCL script to run after the test. -# -# This command runs a series of tests to verify SQLite's ability -# to handle an out-of-memory condition gracefully. It is assumed -# that if this condition occurs a malloc() call will return a -# NULL pointer. Linux, for example, doesn't do that by default. See -# the "BUGS" section of malloc(3). -# -# Each iteration of a loop, the TCL commands in any argument passed -# to the -tclbody switch, followed by the SQL commands in any argument -# passed to the -sqlbody switch are executed. Each iteration the -# Nth call to sqliteMalloc() is made to fail, where N is increased -# each time the loop runs starting from 1. When all commands execute -# successfully, the loop ends. -# -proc do_malloc_test {tn args} { - array set ::mallocopts $args - - set ::go 1 - for {set ::n 1} {$::go} {incr ::n} { - - do_test malloc-$tn.$::n { - - sqlite_malloc_fail 0 - catch {db close} - catch {file delete -force test.db} - catch {file delete -force test.db-journal} - catch {file delete -force test2.db} - catch {file delete -force test2.db-journal} - set ::DB [sqlite3 db test.db] - - if {[info exists ::mallocopts(-tclprep)]} { - eval $::mallocopts(-tclprep) - } - if {[info exists ::mallocopts(-sqlprep)]} { - execsql $::mallocopts(-sqlprep) - } - - sqlite_malloc_fail $::n - set ::mallocbody {} - if {[info exists ::mallocopts(-tclbody)]} { - append ::mallocbody "$::mallocopts(-tclbody)\n" - } - if {[info exists ::mallocopts(-sqlbody)]} { - append ::mallocbody "db eval {$::mallocopts(-sqlbody)}" - } - - set v [catch $::mallocbody msg] - - set leftover [lindex [sqlite_malloc_stat] 2] - if {$leftover>0} { - if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} - set ::go 0 - set v {1 1} - } else { - set v2 [expr {$msg=="" || $msg=="out of memory"}] - if {!$v2} {puts "\nError message returned: $msg"} - lappend v $v2 - } - } {1 1} - - if {[info exists ::mallocopts(-cleanup)]} { - catch $::mallocopts(-cleanup) - } - } - unset ::mallocopts -} - -do_malloc_test 1 -tclprep { - db close -} -tclbody { - if {[catch {sqlite3 db test.db}]} { - error "out of memory" - } -} -sqlbody { - CREATE TABLE t1( - a int, b float, c double, d text, e varchar(20), - primary key(a,b,c) - ); - CREATE INDEX i1 ON t1(a,b); - INSERT INTO t1 VALUES(1,2.3,4.5,'hi','there'); - INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder'); - SELECT * FROM t1; - SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0; - DELETE FROM t1 WHERE a IN (SELECT min(a) FROM t1); - SELECT count(*) FROM t1; -} - -# Ensure that no file descriptors were leaked. -do_test malloc-1.X { - catch {db close} - set sqlite_open_file_count -} {0} - -do_malloc_test 2 -sqlbody { - CREATE TABLE t1(a int, b int, c int); - CREATE INDEX i1 ON t1(a,b); - INSERT INTO t1 VALUES(1,1,'99 abcdefghijklmnopqrstuvwxyz'); - INSERT INTO t1 VALUES(2,4,'98 abcdefghijklmnopqrstuvwxyz'); - INSERT INTO t1 VALUES(3,9,'97 abcdefghijklmnopqrstuvwxyz'); - INSERT INTO t1 VALUES(4,16,'96 abcdefghijklmnopqrstuvwxyz'); - INSERT INTO t1 VALUES(5,25,'95 abcdefghijklmnopqrstuvwxyz'); - INSERT INTO t1 VALUES(6,36,'94 abcdefghijklmnopqrstuvwxyz'); - SELECT 'stuff', count(*) as 'other stuff', max(a+10) FROM t1; - UPDATE t1 SET b=b||b||b||b; - UPDATE t1 SET b=a WHERE a in (10,12,22); - INSERT INTO t1(c,b,a) VALUES(20,10,5); - INSERT INTO t1 SELECT * FROM t1 - WHERE a IN (SELECT a FROM t1 WHERE a<10); - DELETE FROM t1 WHERE a>=10; - DROP INDEX i1; - DELETE FROM t1; -} - -# Ensure that no file descriptors were leaked. -do_test malloc-2.X { - catch {db close} - set sqlite_open_file_count -} {0} - -do_malloc_test 3 -sqlbody { - BEGIN TRANSACTION; - CREATE TABLE t1(a int, b int, c int); - CREATE INDEX i1 ON t1(a,b); - INSERT INTO t1 VALUES(1,1,99); - INSERT INTO t1 VALUES(2,4,98); - INSERT INTO t1 VALUES(3,9,97); - INSERT INTO t1 VALUES(4,16,96); - INSERT INTO t1 VALUES(5,25,95); - INSERT INTO t1 VALUES(6,36,94); - INSERT INTO t1(c,b,a) VALUES(20,10,5); - DELETE FROM t1 WHERE a>=10; - DROP INDEX i1; - DELETE FROM t1; - ROLLBACK; -} - - -# Ensure that no file descriptors were leaked. -do_test malloc-3.X { - catch {db close} - set sqlite_open_file_count -} {0} - -do_malloc_test 4 -sqlbody { - BEGIN TRANSACTION; - CREATE TABLE t1(a int, b int, c int); - CREATE INDEX i1 ON t1(a,b); - INSERT INTO t1 VALUES(1,1,99); - INSERT INTO t1 VALUES(2,4,98); - INSERT INTO t1 VALUES(3,9,97); - INSERT INTO t1 VALUES(4,16,96); - INSERT INTO t1 VALUES(5,25,95); - INSERT INTO t1 VALUES(6,36,94); - UPDATE t1 SET b=a WHERE a in (10,12,22); - INSERT INTO t1 SELECT * FROM t1 - WHERE a IN (SELECT a FROM t1 WHERE a<10); - DROP INDEX i1; - DELETE FROM t1; - COMMIT; -} - -# Ensure that no file descriptors were leaked. -do_test malloc-4.X { - catch {db close} - set sqlite_open_file_count -} {0} - -do_malloc_test 5 -sqlbody { - BEGIN TRANSACTION; - CREATE TABLE t1(a,b); - CREATE TABLE t2(x,y); - CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN - INSERT INTO t2(x,y) VALUES(new.rowid,1); - END; - INSERT INTO t1(a,b) VALUES(2,3); - COMMIT; -} - -# Ensure that no file descriptors were leaked. -do_test malloc-5.X { - catch {db close} - set sqlite_open_file_count -} {0} - -do_malloc_test 6 -sqlprep { - BEGIN TRANSACTION; - CREATE TABLE t1(a); - INSERT INTO t1 VALUES(1); - INSERT INTO t1 SELECT a*2 FROM t1; - INSERT INTO t1 SELECT a*2 FROM t1; - INSERT INTO t1 SELECT a*2 FROM t1; - INSERT INTO t1 SELECT a*2 FROM t1; - INSERT INTO t1 SELECT a*2 FROM t1; - INSERT INTO t1 SELECT a*2 FROM t1; - INSERT INTO t1 SELECT a*2 FROM t1; - INSERT INTO t1 SELECT a*2 FROM t1; - INSERT INTO t1 SELECT a*2 FROM t1; - INSERT INTO t1 SELECT a*2 FROM t1; - DELETE FROM t1 where rowid%5 = 0; - COMMIT; -} -sqlbody { - VACUUM; -} - -do_malloc_test 7 -sqlprep { - CREATE TABLE t1(a, b); - INSERT INTO t1 VALUES(1, 2); - INSERT INTO t1 VALUES(3, 4); - INSERT INTO t1 VALUES(5, 6); - INSERT INTO t1 VALUES(7, randstr(1200,1200)); -} -sqlbody { - SELECT min(a) FROM t1 WHERE a<6 GROUP BY b; - SELECT a FROM t1 WHERE a<6 ORDER BY a; - SELECT b FROM t1 WHERE a>6; -} - -# This block is designed to test that some malloc failures that may -# occur in vdbeapi.c. Specifically, if a malloc failure that occurs -# when converting UTF-16 text to integers and real numbers is handled -# correctly. -# -# This is done by retrieving a string from the database engine and -# manipulating it using the sqlite3_column_*** APIs. This doesn't -# actually return an error to the user when a malloc() fails.. That -# could be viewed as a bug. -# -# These tests only run if UTF-16 support is compiled in. -# -if {$::sqlite_options(utf16)} { - do_malloc_test 8 -tclprep { - set sql "SELECT '[string repeat abc 20]', '[string repeat def 20]', ?" - set ::STMT [sqlite3_prepare $::DB $sql -1 X] - sqlite3_step $::STMT - if { $::tcl_platform(byteOrder)=="littleEndian" } { - set ::bomstr "\xFF\xFE" - } else { - set ::bomstr "\xFE\xFF" - } - append ::bomstr [encoding convertto unicode "123456789_123456789_12345678"] - } -tclbody { - sqlite3_column_text16 $::STMT 0 - sqlite3_column_int $::STMT 0 - sqlite3_column_text16 $::STMT 1 - sqlite3_column_double $::STMT 1 - sqlite3_reset $::STMT - sqlite3_bind_text16 $::STMT 1 $::bomstr 60 - catch {sqlite3_finalize $::STMT} - if {[lindex [sqlite_malloc_stat] 2]<=0} { - error "out of memory" - } - } -cleanup { - sqlite3_finalize $::STMT - } -} - -# This block tests that malloc() failures that occur whilst commiting -# a multi-file transaction are handled correctly. -# -do_malloc_test 9 -sqlprep { - ATTACH 'test2.db' as test2; - CREATE TABLE abc1(a, b, c); - CREATE TABLE test2.abc2(a, b, c); -} -sqlbody { - BEGIN; - INSERT INTO abc1 VALUES(1, 2, 3); - INSERT INTO abc2 VALUES(1, 2, 3); - COMMIT; -} - -# This block tests malloc() failures that occur while opening a -# connection to a database. -do_malloc_test 10 -sqlprep { - CREATE TABLE abc(a, b, c); -} -tclbody { - set ::DB [sqlite3 db2 test.db] - db2 eval {SELECT * FROM sqlite_master} - db2 close -} - -# This block tests malloc() failures that occur within calls to -# sqlite3_create_function(). -do_malloc_test 11 -tclbody { - set rc [sqlite3_create_function $::DB] - if {[string match $rc SQLITE_NOMEM]} { - error "out of memory" - } -} - -do_malloc_test 12 -tclbody { - set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"] - append sql16 "\00\00" - set ::STMT [sqlite3_prepare16 $::DB $sql16 -1 DUMMY] - sqlite3_finalize $::STMT -} - -# Test malloc errors when replaying two hot journals from a 2-file -# transaction. This test only runs on UNIX. -if {$tcl_platform(platform)=="unix"} { - do_malloc_test 13 -tclprep { - set rc [crashsql 1 test2.db { - ATTACH 'test2.db' as aux; - PRAGMA cache_size = 10; - BEGIN; - CREATE TABLE aux.t2(a, b, c); - CREATE TABLE t1(a, b, c); - COMMIT; - }] - if {$rc!="1 {child process exited abnormally}"} { - error "Wrong error message: $rc" - } - } -sqlbody { - ATTACH 'test2.db' as aux; - SELECT * FROM t1; - SELECT * FROM t2; - } -} - -if {$tcl_platform(platform)!="windows"} { -do_malloc_test 14 -tclprep { - catch {db close} - sqlite3 db2 test2.db - db2 eval { - PRAGMA synchronous = 0; - CREATE TABLE t1(a, b); - INSERT INTO t1 VALUES(1, 2); - BEGIN; - INSERT INTO t1 VALUES(3, 4); - } - copy_file test2.db test.db - copy_file test2.db-journal test.db-journal - db2 close -} -tclbody { - sqlite3 db test.db - db eval { - SELECT * FROM t1; - } -} -} - -# Ensure that no file descriptors were leaked. -do_test malloc-99.X { - catch {db close} - set sqlite_open_file_count -} {0} - -sqlite_malloc_fail 0 -finish_test diff --git a/sqlite/test/memdb.test b/sqlite/test/memdb.test deleted file mode 100644 index 0052ce2..0000000 --- a/sqlite/test/memdb.test +++ /dev/null @@ -1,378 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this script is in-memory database backend. -# -# $Id: memdb.test,v 1.13 2005/01/21 04:25:47 danielk1977 Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -ifcapable memorydb { - -# In the following sequence of tests, compute the MD5 sum of the content -# of a table, make lots of modifications to that table, then do a rollback. -# Verify that after the rollback, the MD5 checksum is unchanged. -# -# These tests were browed from trans.tcl. -# -do_test memdb-1.1 { - db close - sqlite3 db :memory: - # sqlite3 db test.db - execsql { - BEGIN; - CREATE TABLE t3(x TEXT); - INSERT INTO t3 VALUES(randstr(10,400)); - INSERT INTO t3 VALUES(randstr(10,400)); - INSERT INTO t3 SELECT randstr(10,400) FROM t3; - INSERT INTO t3 SELECT randstr(10,400) FROM t3; - INSERT INTO t3 SELECT randstr(10,400) FROM t3; - INSERT INTO t3 SELECT randstr(10,400) FROM t3; - INSERT INTO t3 SELECT randstr(10,400) FROM t3; - INSERT INTO t3 SELECT randstr(10,400) FROM t3; - INSERT INTO t3 SELECT randstr(10,400) FROM t3; - INSERT INTO t3 SELECT randstr(10,400) FROM t3; - INSERT INTO t3 SELECT randstr(10,400) FROM t3; - COMMIT; - SELECT count(*) FROM t3; - } -} {1024} - -# The following procedure computes a "signature" for table "t3". If -# T3 changes in any way, the signature should change. -# -# This is used to test ROLLBACK. We gather a signature for t3, then -# make lots of changes to t3, then rollback and take another signature. -# The two signatures should be the same. -# -proc signature {{fn {}}} { - set rx [db eval {SELECT x FROM t3}] - # set r1 [md5 $rx\n] - if {$fn!=""} { - # set fd [open $fn w] - # puts $fd $rx - # close $fd - } - # set r [db eval {SELECT count(*), md5sum(x) FROM t3}] - # puts "SIG($fn)=$r1" - return [list [string length $rx] $rx] -} - -# Do rollbacks. Make sure the signature does not change. -# -set limit 10 -for {set i 2} {$i<=$limit} {incr i} { - set ::sig [signature one] - # puts "sig=$sig" - set cnt [lindex $::sig 0] - if {$i%2==0} { - execsql {PRAGMA synchronous=FULL} - } else { - execsql {PRAGMA synchronous=NORMAL} - } - do_test memdb-1.$i.1-$cnt { - execsql { - BEGIN; - DELETE FROM t3 WHERE random()%10!=0; - INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; - INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; - ROLLBACK; - } - set sig2 [signature two] - } $sig - # puts "sig2=$sig2" - # if {$sig2!=$sig} exit - do_test memdb-1.$i.2-$cnt { - execsql { - BEGIN; - DELETE FROM t3 WHERE random()%10!=0; - INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; - DELETE FROM t3 WHERE random()%10!=0; - INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; - ROLLBACK; - } - signature - } $sig - if {$i<$limit} { - do_test memdb-1.$i.9-$cnt { - execsql { - INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0; - } - } {} - } - set ::pager_old_format 0 -} - -integrity_check memdb-2.1 - -do_test memdb-3.1 { - execsql { - CREATE TABLE t4(a,b,c,d); - BEGIN; - INSERT INTO t4 VALUES(1,2,3,4); - SELECT * FROM t4; - } -} {1 2 3 4} -do_test memdb-3.2 { - execsql { - SELECT name FROM sqlite_master WHERE type='table'; - } -} {t3 t4} -do_test memdb-3.3 { - execsql { - DROP TABLE t4; - SELECT name FROM sqlite_master WHERE type='table'; - } -} {t3} -do_test memdb-3.4 { - execsql { - ROLLBACK; - SELECT name FROM sqlite_master WHERE type='table'; - } -} {t3 t4} - -# Create tables for the first group of tests. -# -do_test memdb-4.0 { - execsql { - CREATE TABLE t1(a, b, c, UNIQUE(a,b)); - CREATE TABLE t2(x); - SELECT c FROM t1 ORDER BY c; - } -} {} - -# Six columns of configuration data as follows: -# -# i The reference number of the test -# conf The conflict resolution algorithm on the BEGIN statement -# cmd An INSERT or REPLACE command to execute against table t1 -# t0 True if there is an error from $cmd -# t1 Content of "c" column of t1 assuming no error in $cmd -# t2 Content of "x" column of t2 -# -foreach {i conf cmd t0 t1 t2} { - 1 {} INSERT 1 {} 1 - 2 {} {INSERT OR IGNORE} 0 3 1 - 3 {} {INSERT OR REPLACE} 0 4 1 - 4 {} REPLACE 0 4 1 - 5 {} {INSERT OR FAIL} 1 {} 1 - 6 {} {INSERT OR ABORT} 1 {} 1 - 7 {} {INSERT OR ROLLBACK} 1 {} {} -} { - do_test memdb-4.$i { - if {$conf!=""} {set conf "ON CONFLICT $conf"} - set r0 [catch {execsql [subst { - DELETE FROM t1; - DELETE FROM t2; - INSERT INTO t1 VALUES(1,2,3); - BEGIN $conf; - INSERT INTO t2 VALUES(1); - $cmd INTO t1 VALUES(1,2,4); - }]} r1] - catch {execsql {COMMIT}} - if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]} - set r2 [execsql {SELECT x FROM t2}] - list $r0 $r1 $r2 - } [list $t0 $t1 $t2] -} - -do_test memdb-5.0 { - execsql { - DROP TABLE t2; - DROP TABLE t3; - CREATE TABLE t2(a,b,c); - INSERT INTO t2 VALUES(1,2,1); - INSERT INTO t2 VALUES(2,3,2); - INSERT INTO t2 VALUES(3,4,1); - INSERT INTO t2 VALUES(4,5,4); - SELECT c FROM t2 ORDER BY b; - CREATE TABLE t3(x); - INSERT INTO t3 VALUES(1); - } -} {1 2 1 4} - -# Six columns of configuration data as follows: -# -# i The reference number of the test -# conf1 The conflict resolution algorithm on the UNIQUE constraint -# conf2 The conflict resolution algorithm on the BEGIN statement -# cmd An UPDATE command to execute against table t1 -# t0 True if there is an error from $cmd -# t1 Content of "b" column of t1 assuming no error in $cmd -# t2 Content of "x" column of t3 -# -foreach {i conf1 conf2 cmd t0 t1 t2} { - 1 {} {} UPDATE 1 {6 7 8 9} 1 - 2 REPLACE {} UPDATE 0 {7 6 9} 1 - 3 IGNORE {} UPDATE 0 {6 7 3 9} 1 - 4 FAIL {} UPDATE 1 {6 7 3 4} 1 - 5 ABORT {} UPDATE 1 {1 2 3 4} 1 - 6 ROLLBACK {} UPDATE 1 {1 2 3 4} 0 - 7 REPLACE {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1 - 8 IGNORE {} {UPDATE OR REPLACE} 0 {7 6 9} 1 - 9 FAIL {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1 - 10 ABORT {} {UPDATE OR REPLACE} 0 {7 6 9} 1 - 11 ROLLBACK {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1 - 12 {} {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1 - 13 {} {} {UPDATE OR REPLACE} 0 {7 6 9} 1 - 14 {} {} {UPDATE OR FAIL} 1 {6 7 3 4} 1 - 15 {} {} {UPDATE OR ABORT} 1 {1 2 3 4} 1 - 16 {} {} {UPDATE OR ROLLBACK} 1 {1 2 3 4} 0 -} { - if {$t0} {set t1 {column a is not unique}} - do_test memdb-5.$i { - if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"} - if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"} - set r0 [catch {execsql [subst { - DROP TABLE t1; - CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1); - INSERT INTO t1 SELECT * FROM t2; - UPDATE t3 SET x=0; - BEGIN $conf2; - $cmd t3 SET x=1; - $cmd t1 SET b=b*2; - $cmd t1 SET a=c+5; - }]} r1] - catch {execsql {COMMIT}} - if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]} - set r2 [execsql {SELECT x FROM t3}] - list $r0 $r1 $r2 - } [list $t0 $t1 $t2] -} - -do_test memdb-6.1 { - execsql { - SELECT * FROM t2; - } -} {1 2 1 2 3 2 3 4 1 4 5 4} -do_test memdb-6.2 { - execsql { - BEGIN; - DROP TABLE t2; - SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1; - } -} {t1 t3 t4} -do_test memdb-6.3 { - execsql { - ROLLBACK; - SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1; - } -} {t1 t2 t3 t4} -do_test memdb-6.4 { - execsql { - SELECT * FROM t2; - } -} {1 2 1 2 3 2 3 4 1 4 5 4} -ifcapable compound { -do_test memdb-6.5 { - execsql { - SELECT a FROM t2 UNION SELECT b FROM t2 ORDER BY 1; - } -} {1 2 3 4 5} -} ;# ifcapable compound -do_test memdb-6.6 { - execsql { - CREATE INDEX i2 ON t2(c); - SELECT a FROM t2 ORDER BY c; - } -} {1 3 2 4} -do_test memdb-6.6 { - execsql { - SELECT a FROM t2 ORDER BY c DESC; - } -} {4 2 3 1} -do_test memdb-6.7 { - execsql { - BEGIN; - CREATE TABLE t5(x,y); - INSERT INTO t5 VALUES(1,2); - SELECT * FROM t5; - } -} {1 2} -do_test memdb-6.8 { - execsql { - SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1; - } -} {t1 t2 t3 t4 t5} -do_test memdb-6.9 { - execsql { - ROLLBACK; - SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1; - } -} {t1 t2 t3 t4} -do_test memdb-6.10 { - execsql { - CREATE TABLE t5(x PRIMARY KEY, y UNIQUE); - SELECT * FROM t5; - } -} {} -do_test memdb-6.11 { - execsql { - SELECT * FROM t5 ORDER BY y DESC; - } -} {} -do_test memdb-6.12 { - execsql { - INSERT INTO t5 VALUES(1,2); - INSERT INTO t5 VALUES(3,4); - REPLACE INTO t5 VALUES(1,4); - SELECT rowid,* FROM t5; - } -} {3 1 4} -do_test memdb-6.13 { - execsql { - DELETE FROM t5 WHERE x>5; - SELECT * FROM t5; - } -} {1 4} -do_test memdb-6.14 { - execsql { - DELETE FROM t5 WHERE y<3; - SELECT * FROM t5; - } -} {1 4} -do_test memdb-6.15 { - execsql { - DELETE FROM t5 WHERE x>0; - SELECT * FROM t5; - } -} {} - -ifcapable subquery { - do_test memdb-7.1 { - execsql { - CREATE TABLE t6(x); - INSERT INTO t6 VALUES(1); - INSERT INTO t6 SELECT x+1 FROM t6; - INSERT INTO t6 SELECT x+2 FROM t6; - INSERT INTO t6 SELECT x+4 FROM t6; - INSERT INTO t6 SELECT x+8 FROM t6; - INSERT INTO t6 SELECT x+16 FROM t6; - INSERT INTO t6 SELECT x+32 FROM t6; - INSERT INTO t6 SELECT x+64 FROM t6; - INSERT INTO t6 SELECT x+128 FROM t6; - SELECT count(*) FROM (SELECT DISTINCT x FROM t6); - } - } {256} - for {set i 1} {$i<=256} {incr i} { - do_test memdb-7.2.$i { - execsql "DELETE FROM t6 WHERE x=\ - (SELECT x FROM t6 ORDER BY random() LIMIT 1)" - execsql {SELECT count(*) FROM t6} - } [expr {256-$i}] - } -} - -} ;# ifcapable memorydb - -finish_test diff --git a/sqlite/test/memleak.test b/sqlite/test/memleak.test deleted file mode 100644 index 78552e8..0000000 --- a/sqlite/test/memleak.test +++ /dev/null @@ -1,97 +0,0 @@ -# 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 runs all tests. -# -# $Id: memleak.test,v 1.8 2005/01/17 07:53:44 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -rename finish_test really_finish_test -proc finish_test {} { - catch {db close} - memleak_check -} - -if {[file exists ./sqlite_test_count]} { - set COUNT [exec cat ./sqlite_test_count] -} else { - set COUNT 3 -} - -# LeakList will hold a list of the number of unfreed mallocs after -# each round of the test. This number should be constant. If it -# grows, it may mean there is a memory leak in the library. -# -set LeakList {} - -set EXCLUDE { - all.test - quick.test - malloc.test - misuse.test - memleak.test - btree2.test - trans.test - crash.test - autovacuum_crash.test -} -# Test files btree2.test and btree4.test don't work if the -# SQLITE_DEFAULT_AUTOVACUUM macro is defined to true (because they depend -# on tables being allocated starting at page 2). -# -ifcapable default_autovacuum { - lappend EXCLUDE btree2.test - lappend EXCLUDE btree4.test -} - -if {[sqlite3 -has-codec]} { - # lappend EXCLUDE -} -if {[llength $argv]>0} { - set FILELIST $argv - set argv {} -} else { - set FILELIST [lsort -dictionary [glob $testdir/*.test]] -} - -foreach testfile $FILELIST { - set tail [file tail $testfile] - if {[lsearch -exact $EXCLUDE $tail]>=0} continue - set LeakList {} - for {set COUNTER 0} {$COUNTER<$COUNT} {incr COUNTER} { - source $testfile - if {[info exists Leak]} { - lappend LeakList $Leak - } - } - if {$LeakList!=""} { - puts -nonewline memory-leak-test-$tail... - incr ::nTest - foreach x $LeakList { - if {$x!=[lindex $LeakList 0]} { - puts " failed! ($LeakList)" - incr ::nErr - lappend ::failList memory-leak-test-$tail - break - } - } - puts " Ok" - } -} -really_finish_test - -# Run the malloc tests and the misuse test after memory leak detection. -# Both tests leak memory. -# -#catch {source $testdir/misuse.test} -#catch {source $testdir/malloc.test} - -really_finish_test diff --git a/sqlite/test/minmax.test b/sqlite/test/minmax.test deleted file mode 100644 index fd0ba4e..0000000 --- a/sqlite/test/minmax.test +++ /dev/null @@ -1,384 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing SELECT statements that contain -# aggregate min() and max() functions and which are handled as -# as a special case. -# -# $Id: minmax.test,v 1.16 2005/01/21 04:25:47 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -do_test minmax-1.0 { - execsql { - BEGIN; - CREATE TABLE t1(x, y); - INSERT INTO t1 VALUES(1,1); - INSERT INTO t1 VALUES(2,2); - INSERT INTO t1 VALUES(3,2); - INSERT INTO t1 VALUES(4,3); - INSERT INTO t1 VALUES(5,3); - INSERT INTO t1 VALUES(6,3); - INSERT INTO t1 VALUES(7,3); - INSERT INTO t1 VALUES(8,4); - INSERT INTO t1 VALUES(9,4); - INSERT INTO t1 VALUES(10,4); - INSERT INTO t1 VALUES(11,4); - INSERT INTO t1 VALUES(12,4); - INSERT INTO t1 VALUES(13,4); - INSERT INTO t1 VALUES(14,4); - INSERT INTO t1 VALUES(15,4); - INSERT INTO t1 VALUES(16,5); - INSERT INTO t1 VALUES(17,5); - INSERT INTO t1 VALUES(18,5); - INSERT INTO t1 VALUES(19,5); - INSERT INTO t1 VALUES(20,5); - COMMIT; - SELECT DISTINCT y FROM t1 ORDER BY y; - } -} {1 2 3 4 5} - -do_test minmax-1.1 { - set sqlite_search_count 0 - execsql {SELECT min(x) FROM t1} -} {1} -do_test minmax-1.2 { - set sqlite_search_count -} {19} -do_test minmax-1.3 { - set sqlite_search_count 0 - execsql {SELECT max(x) FROM t1} -} {20} -do_test minmax-1.4 { - set sqlite_search_count -} {19} -do_test minmax-1.5 { - execsql {CREATE INDEX t1i1 ON t1(x)} - set sqlite_search_count 0 - execsql {SELECT min(x) FROM t1} -} {1} -do_test minmax-1.6 { - set sqlite_search_count -} {2} -do_test minmax-1.7 { - set sqlite_search_count 0 - execsql {SELECT max(x) FROM t1} -} {20} -do_test minmax-1.8 { - set sqlite_search_count -} {1} -do_test minmax-1.9 { - set sqlite_search_count 0 - execsql {SELECT max(y) FROM t1} -} {5} -do_test minmax-1.10 { - set sqlite_search_count -} {19} - -do_test minmax-2.0 { - execsql { - CREATE TABLE t2(a INTEGER PRIMARY KEY, b); - INSERT INTO t2 SELECT * FROM t1; - } - set sqlite_search_count 0 - execsql {SELECT min(a) FROM t2} -} {1} -do_test minmax-2.1 { - set sqlite_search_count -} {0} -do_test minmax-2.2 { - set sqlite_search_count 0 - execsql {SELECT max(a) FROM t2} -} {20} -do_test minmax-2.3 { - set sqlite_search_count -} {0} - -do_test minmax-3.0 { - ifcapable subquery { - execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)} - } else { - db function max_a_t2 {execsql {SELECT max(a) FROM t2}} - execsql {INSERT INTO t2 VALUES(max_a_t2()+1,999)} - } - set sqlite_search_count 0 - execsql {SELECT max(a) FROM t2} -} {21} -do_test minmax-3.1 { - set sqlite_search_count -} {0} -do_test minmax-3.2 { - ifcapable subquery { - execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)} - } else { - db function max_a_t2 {execsql {SELECT max(a) FROM t2}} - execsql {INSERT INTO t2 VALUES(max_a_t2()+1,999)} - } - set sqlite_search_count 0 - ifcapable subquery { - execsql { SELECT b FROM t2 WHERE a=(SELECT max(a) FROM t2) } - } else { - execsql { SELECT b FROM t2 WHERE a=max_a_t2() } - } -} {999} -do_test minmax-3.3 { - set sqlite_search_count -} {0} - -ifcapable {compound && subquery} { - do_test minmax-4.1 { - execsql { - SELECT coalesce(min(x+0),-1), coalesce(max(x+0),-1) FROM - (SELECT * FROM t1 UNION SELECT NULL as 'x', NULL as 'y') - } - } {1 20} - do_test minmax-4.2 { - execsql { - SELECT y, sum(x) FROM - (SELECT null, y+1 FROM t1 UNION SELECT * FROM t1) - GROUP BY y ORDER BY y; - } - } {1 1.0 2 5.0 3 22.0 4 92.0 5 90.0 6 0.0} - do_test minmax-4.3 { - execsql { - SELECT y, count(x), count(*) FROM - (SELECT null, y+1 FROM t1 UNION SELECT * FROM t1) - GROUP BY y ORDER BY y; - } - } {1 1 1 2 2 3 3 4 5 4 8 9 5 5 6 6 0 1} -} ;# ifcapable compound - -# Make sure the min(x) and max(x) optimizations work on empty tables -# including empty tables with indices. Ticket #296. -# -do_test minmax-5.1 { - execsql { - CREATE TABLE t3(x INTEGER UNIQUE NOT NULL); - SELECT coalesce(min(x),999) FROM t3; - } -} {999} -do_test minmax-5.2 { - execsql { - SELECT coalesce(min(rowid),999) FROM t3; - } -} {999} -do_test minmax-5.3 { - execsql { - SELECT coalesce(max(x),999) FROM t3; - } -} {999} -do_test minmax-5.4 { - execsql { - SELECT coalesce(max(rowid),999) FROM t3; - } -} {999} -do_test minmax-5.5 { - execsql { - SELECT coalesce(max(rowid),999) FROM t3 WHERE rowid<25; - } -} {999} - -# Make sure the min(x) and max(x) optimizations work when there -# is a LIMIT clause. Ticket #396. -# -do_test minmax-6.1 { - execsql { - SELECT min(a) FROM t2 LIMIT 1 - } -} {1} -do_test minmax-6.2 { - execsql { - SELECT max(a) FROM t2 LIMIT 3 - } -} {22} -do_test minmax-6.3 { - execsql { - SELECT min(a) FROM t2 LIMIT 0,100 - } -} {1} -do_test minmax-6.4 { - execsql { - SELECT max(a) FROM t2 LIMIT 1,100 - } -} {} -do_test minmax-6.5 { - execsql { - SELECT min(x) FROM t3 LIMIT 1 - } -} {{}} -do_test minmax-6.6 { - execsql { - SELECT max(x) FROM t3 LIMIT 0 - } -} {} -do_test minmax-6.7 { - execsql { - SELECT max(a) FROM t2 LIMIT 0 - } -} {} - -# Make sure the max(x) and min(x) optimizations work for nested -# queries. Ticket #587. -# -do_test minmax-7.1 { - execsql { - SELECT max(x) FROM t1; - } -} 20 -ifcapable subquery { - do_test minmax-7.2 { - execsql { - SELECT * FROM (SELECT max(x) FROM t1); - } - } 20 -} -do_test minmax-7.3 { - execsql { - SELECT min(x) FROM t1; - } -} 1 -ifcapable subquery { - do_test minmax-7.4 { - execsql { - SELECT * FROM (SELECT min(x) FROM t1); - } - } 1 -} - -# Make sure min(x) and max(x) work correctly when the datatype is -# TEXT instead of NUMERIC. Ticket #623. -# -do_test minmax-8.1 { - execsql { - CREATE TABLE t4(a TEXT); - INSERT INTO t4 VALUES('1234'); - INSERT INTO t4 VALUES('234'); - INSERT INTO t4 VALUES('34'); - SELECT min(a), max(a) FROM t4; - } -} {1234 34} -do_test minmax-8.2 { - execsql { - CREATE TABLE t5(a INTEGER); - INSERT INTO t5 VALUES('1234'); - INSERT INTO t5 VALUES('234'); - INSERT INTO t5 VALUES('34'); - SELECT min(a), max(a) FROM t5; - } -} {34 1234} - -# Ticket #658: Test the min()/max() optimization when the FROM clause -# is a subquery. -# -ifcapable {compound && subquery} { - do_test minmax-9.1 { - execsql { - SELECT max(rowid) FROM ( - SELECT max(rowid) FROM t4 UNION SELECT max(rowid) FROM t5 - ) - } - } {1} - do_test minmax-9.2 { - execsql { - SELECT max(rowid) FROM ( - SELECT max(rowid) FROM t4 EXCEPT SELECT max(rowid) FROM t5 - ) - } - } {{}} -} ;# ifcapable compound&&subquery - -# If there is a NULL in an aggregate max() or min(), ignore it. An -# aggregate min() or max() will only return NULL if all values are NULL. -# -do_test minmax-10.1 { - execsql { - CREATE TABLE t6(x); - INSERT INTO t6 VALUES(1); - INSERT INTO t6 VALUES(2); - INSERT INTO t6 VALUES(NULL); - SELECT coalesce(min(x),-1) FROM t6; - } -} {1} -do_test minmax-10.2 { - execsql { - SELECT max(x) FROM t6; - } -} {2} -do_test minmax-10.3 { - execsql { - CREATE INDEX i6 ON t6(x); - SELECT coalesce(min(x),-1) FROM t6; - } -} {1} -do_test minmax-10.4 { - execsql { - SELECT max(x) FROM t6; - } -} {2} -do_test minmax-10.5 { - execsql { - DELETE FROM t6 WHERE x NOT NULL; - SELECT count(*) FROM t6; - } -} 1 -do_test minmax-10.6 { - execsql { - SELECT count(x) FROM t6; - } -} 0 -ifcapable subquery { - do_test minmax-10.7 { - execsql { - SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6); - } - } {{} {}} -} -do_test minmax-10.8 { - execsql { - SELECT min(x), max(x) FROM t6; - } -} {{} {}} -do_test minmax-10.9 { - execsql { - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - INSERT INTO t6 SELECT * FROM t6; - SELECT count(*) FROM t6; - } -} 1024 -do_test minmax-10.10 { - execsql { - SELECT count(x) FROM t6; - } -} 0 -ifcapable subquery { - do_test minmax-10.11 { - execsql { - SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6); - } - } {{} {}} -} -do_test minmax-10.12 { - execsql { - SELECT min(x), max(x) FROM t6; - } -} {{} {}} - - -finish_test diff --git a/sqlite/test/misc1.test b/sqlite/test/misc1.test deleted file mode 100644 index ef32f09..0000000 --- a/sqlite/test/misc1.test +++ /dev/null @@ -1,564 +0,0 @@ -# 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 implements regression tests for SQLite library. -# -# This file implements tests for miscellanous features that were -# left out of other test files. -# -# $Id: misc1.test,v 1.33 2005/01/21 04:25:47 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Mimic the SQLite 2 collation type NUMERIC. -db collate numeric numeric_collate -proc numeric_collate {lhs rhs} { - if {$lhs == $rhs} {return 0} - return [expr ($lhs>$rhs)?1:-1] -} - -# Mimic the SQLite 2 collation type TEXT. -db collate text text_collate -proc numeric_collate {lhs rhs} { - return [string compare $lhs $rhs] -} - -# Test the creation and use of tables that have a large number -# of columns. -# -do_test misc1-1.1 { - set cmd "CREATE TABLE manycol(x0 text" - for {set i 1} {$i<=99} {incr i} { - append cmd ",x$i text" - } - append cmd ")"; - execsql $cmd - set cmd "INSERT INTO manycol VALUES(0" - for {set i 1} {$i<=99} {incr i} { - append cmd ",$i" - } - append cmd ")"; - execsql $cmd - execsql "SELECT x99 FROM manycol" -} 99 -do_test misc1-1.2 { - execsql {SELECT x0, x10, x25, x50, x75 FROM manycol} -} {0 10 25 50 75} -do_test misc1-1.3.1 { - for {set j 100} {$j<=1000} {incr j 100} { - set cmd "INSERT INTO manycol VALUES($j" - for {set i 1} {$i<=99} {incr i} { - append cmd ",[expr {$i+$j}]" - } - append cmd ")" - execsql $cmd - } - execsql {SELECT x50 FROM manycol ORDER BY x80+0} -} {50 150 250 350 450 550 650 750 850 950 1050} -do_test misc1-1.3.2 { - execsql {SELECT x50 FROM manycol ORDER BY x80} -} {1050 150 250 350 450 550 650 750 50 850 950} -do_test misc1-1.4 { - execsql {SELECT x75 FROM manycol WHERE x50=350} -} 375 -do_test misc1-1.5 { - execsql {SELECT x50 FROM manycol WHERE x99=599} -} 550 -do_test misc1-1.6 { - execsql {CREATE INDEX manycol_idx1 ON manycol(x99)} - execsql {SELECT x50 FROM manycol WHERE x99=899} -} 850 -do_test misc1-1.7 { - execsql {SELECT count(*) FROM manycol} -} 11 -do_test misc1-1.8 { - execsql {DELETE FROM manycol WHERE x98=1234} - execsql {SELECT count(*) FROM manycol} -} 11 -do_test misc1-1.9 { - execsql {DELETE FROM manycol WHERE x98=998} - execsql {SELECT count(*) FROM manycol} -} 10 -do_test misc1-1.10 { - execsql {DELETE FROM manycol WHERE x99=500} - execsql {SELECT count(*) FROM manycol} -} 10 -do_test misc1-1.11 { - execsql {DELETE FROM manycol WHERE x99=599} - execsql {SELECT count(*) FROM manycol} -} 9 - -# Check GROUP BY expressions that name two or more columns. -# -do_test misc1-2.1 { - execsql { - BEGIN TRANSACTION; - CREATE TABLE agger(one text, two text, three text, four text); - INSERT INTO agger VALUES(1, 'one', 'hello', 'yes'); - INSERT INTO agger VALUES(2, 'two', 'howdy', 'no'); - INSERT INTO agger VALUES(3, 'thr', 'howareya', 'yes'); - INSERT INTO agger VALUES(4, 'two', 'lothere', 'yes'); - INSERT INTO agger VALUES(5, 'one', 'atcha', 'yes'); - INSERT INTO agger VALUES(6, 'two', 'hello', 'no'); - COMMIT - } - execsql {SELECT count(*) FROM agger} -} 6 -do_test misc1-2.2 { - execsql {SELECT sum(one), two, four FROM agger - GROUP BY two, four ORDER BY sum(one) desc} -} {8.0 two no 6.0 one yes 4.0 two yes 3.0 thr yes} -do_test misc1-2.3 { - execsql {SELECT sum((one)), (two), (four) FROM agger - GROUP BY (two), (four) ORDER BY sum(one) desc} -} {8.0 two no 6.0 one yes 4.0 two yes 3.0 thr yes} - -# Here's a test for a bug found by Joel Lucsy. The code below -# was causing an assertion failure. -# -do_test misc1-3.1 { - set r [execsql { - CREATE TABLE t1(a); - INSERT INTO t1 VALUES('hi'); - PRAGMA full_column_names=on; - SELECT rowid, * FROM t1; - }] - lindex $r 1 -} {hi} - -# Here's a test for yet another bug found by Joel Lucsy. The code -# below was causing an assertion failure. -# -do_test misc1-4.1 { - execsql { - BEGIN; - CREATE TABLE t2(a); - INSERT INTO t2 VALUES('This is a long string to use up a lot of disk -'); - UPDATE t2 SET a=a||a||a||a; - INSERT INTO t2 SELECT '1 - ' || a FROM t2; - INSERT INTO t2 SELECT '2 - ' || a FROM t2; - INSERT INTO t2 SELECT '3 - ' || a FROM t2; - INSERT INTO t2 SELECT '4 - ' || a FROM t2; - INSERT INTO t2 SELECT '5 - ' || a FROM t2; - INSERT INTO t2 SELECT '6 - ' || a FROM t2; - COMMIT; - SELECT count(*) FROM t2; - } -} {64} - -# Make sure we actually see a semicolon or end-of-file in the SQL input -# before executing a command. Thus if "WHERE" is misspelled on an UPDATE, -# the user won't accidently update every record. -# -do_test misc1-5.1 { - catchsql { - CREATE TABLE t3(a,b); - INSERT INTO t3 VALUES(1,2); - INSERT INTO t3 VALUES(3,4); - UPDATE t3 SET a=0 WHEREwww b=2; - } -} {1 {near "WHEREwww": syntax error}} -do_test misc1-5.2 { - execsql { - SELECT * FROM t3 ORDER BY a; - } -} {1 2 3 4} - -# Certain keywords (especially non-standard keywords like "REPLACE") can -# also be used as identifiers. The way this works in the parser is that -# the parser first detects a syntax error, the error handling routine -# sees that the special keyword caused the error, then replaces the keyword -# with "ID" and tries again. -# -# Check the operation of this logic. -# -do_test misc1-6.1 { - catchsql { - CREATE TABLE t4( - abort, asc, begin, cluster, conflict, copy, delimiters, desc, end, - explain, fail, ignore, key, offset, pragma, replace, temp, - vacuum, view - ); - } -} {0 {}} -do_test misc1-6.2 { - catchsql { - INSERT INTO t4 - VALUES(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19); - } -} {0 {}} -do_test misc1-6.3 { - execsql { - SELECT * FROM t4 - } -} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19} -do_test misc1-6.4 { - execsql { - SELECT abort+asc,max(key,pragma,temp) FROM t4 - } -} {3 17} - -# Test for multi-column primary keys, and for multiple primary keys. -# -do_test misc1-7.1 { - catchsql { - CREATE TABLE error1( - a TYPE PRIMARY KEY, - b TYPE PRIMARY KEY - ); - } -} {1 {table "error1" has more than one primary key}} -do_test misc1-7.2 { - catchsql { - CREATE TABLE error1( - a INTEGER PRIMARY KEY, - b TYPE PRIMARY KEY - ); - } -} {1 {table "error1" has more than one primary key}} -do_test misc1-7.3 { - execsql { - CREATE TABLE t5(a,b,c,PRIMARY KEY(a,b)); - INSERT INTO t5 VALUES(1,2,3); - SELECT * FROM t5 ORDER BY a; - } -} {1 2 3} -do_test misc1-7.4 { - catchsql { - INSERT INTO t5 VALUES(1,2,4); - } -} {1 {columns a, b are not unique}} -do_test misc1-7.5 { - catchsql { - INSERT INTO t5 VALUES(0,2,4); - } -} {0 {}} -do_test misc1-7.6 { - execsql { - SELECT * FROM t5 ORDER BY a; - } -} {0 2 4 1 2 3} - -do_test misc1-8.1 { - catchsql { - SELECT *; - } -} {1 {no tables specified}} -do_test misc1-8.2 { - catchsql { - SELECT t1.*; - } -} {1 {no such table: t1}} - -execsql { - DROP TABLE t1; - DROP TABLE t2; - DROP TABLE t3; - DROP TABLE t4; -} - -# 64-bit integers are represented exactly. -# -do_test misc1-9.1 { - catchsql { - CREATE TABLE t1(a unique not null, b unique not null); - INSERT INTO t1 VALUES('a',1234567890123456789); - INSERT INTO t1 VALUES('b',1234567891123456789); - INSERT INTO t1 VALUES('c',1234567892123456789); - SELECT * FROM t1; - } -} {0 {a 1234567890123456789 b 1234567891123456789 c 1234567892123456789}} - -# A WHERE clause is not allowed to contain more than 99 terms. Check to -# make sure this limit is enforced. -# -do_test misc1-10.0 { - execsql {SELECT count(*) FROM manycol} -} {9} -do_test misc1-10.1 { - set ::where {WHERE x0>=0} - for {set i 1} {$i<=99} {incr i} { - append ::where " AND x$i<>0" - } - catchsql "SELECT count(*) FROM manycol $::where" -} {0 9} -do_test misc1-10.2 { - catchsql "SELECT count(*) FROM manycol $::where AND rowid>0" -} {1 {WHERE clause too complex - no more than 100 terms allowed}} -do_test misc1-10.3 { - regsub "x0>=0" $::where "x0=0" ::where - catchsql "DELETE FROM manycol $::where" -} {0 {}} -do_test misc1-10.4 { - execsql {SELECT count(*) FROM manycol} -} {8} -do_test misc1-10.5 { - catchsql "DELETE FROM manycol $::where AND rowid>0" -} {1 {WHERE clause too complex - no more than 100 terms allowed}} -do_test misc1-10.6 { - execsql {SELECT x1 FROM manycol WHERE x0=100} -} {101} -do_test misc1-10.7 { - regsub "x0=0" $::where "x0=100" ::where - catchsql "UPDATE manycol SET x1=x1+1 $::where" -} {0 {}} -do_test misc1-10.8 { - execsql {SELECT x1 FROM manycol WHERE x0=100} -} {102} -do_test misc1-10.9 { - catchsql "UPDATE manycol SET x1=x1+1 $::where AND rowid>0" -} {1 {WHERE clause too complex - no more than 100 terms allowed}} -do_test misc1-10.10 { - execsql {SELECT x1 FROM manycol WHERE x0=100} -} {102} - -# Make sure the initialization works even if a database is opened while -# another process has the database locked. -# -# Update for v3: The BEGIN doesn't lock the database so the schema is read -# and the SELECT returns successfully. -do_test misc1-11.1 { - execsql {BEGIN} - execsql {UPDATE t1 SET a=0 WHERE 0} - sqlite3 db2 test.db - set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg] - lappend rc $msg -# v2 result: {1 {database is locked}} -} {0 3} -do_test misc1-11.2 { - execsql {COMMIT} - set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg] - db2 close - lappend rc $msg -} {0 3} - -# Make sure string comparisons really do compare strings in format4+. -# Similar tests in the format3.test file show that for format3 and earlier -# all comparisions where numeric if either operand looked like a number. -# -do_test misc1-12.1 { - execsql {SELECT '0'=='0.0'} -} {0} -do_test misc1-12.2 { - execsql {SELECT '0'==0.0} -} {0} -do_test misc1-12.3 { - execsql {SELECT '12345678901234567890'=='12345678901234567891'} -} {0} -do_test misc1-12.4 { - execsql { - CREATE TABLE t6(a INT UNIQUE, b TEXT UNIQUE); - INSERT INTO t6 VALUES('0','0.0'); - SELECT * FROM t6; - } -} {0 0.0} -do_test misc1-12.5 { - execsql { - INSERT OR IGNORE INTO t6 VALUES(0.0,'x'); - SELECT * FROM t6; - } -} {0 0.0} -do_test misc1-12.6 { - execsql { - INSERT OR IGNORE INTO t6 VALUES('y',0); - SELECT * FROM t6; - } -} {0 0.0 y 0} -do_test misc1-12.7 { - execsql { - CREATE TABLE t7(x INTEGER, y TEXT, z); - INSERT INTO t7 VALUES(0,0,1); - INSERT INTO t7 VALUES(0.0,0,2); - INSERT INTO t7 VALUES(0,0.0,3); - INSERT INTO t7 VALUES(0.0,0.0,4); - SELECT DISTINCT x, y FROM t7 ORDER BY z; - } -} {0 0 0 0.0} -do_test misc1-12.8 { - execsql { - SELECT min(z), max(z), count(z) FROM t7 GROUP BY x ORDER BY 1; - } -} {1 4 4} -do_test misc1-12.9 { - execsql { - SELECT min(z), max(z), count(z) FROM t7 GROUP BY y ORDER BY 1; - } -} {1 2 2 3 4 2} - -# This used to be an error. But we changed the code so that arbitrary -# identifiers can be used as a collating sequence. Collation is by text -# if the identifier contains "text", "blob", or "clob" and is numeric -# otherwise. -# -# Update: In v3, it is an error again. -# -#do_test misc1-12.10 { -# catchsql { -# SELECT * FROM t6 ORDER BY a COLLATE unknown; -# } -#} {0 {0 0.0 y 0}} -do_test misc1-12.11 { - execsql { - CREATE TABLE t8(x TEXT COLLATE numeric, y INTEGER COLLATE text, z); - INSERT INTO t8 VALUES(0,0,1); - INSERT INTO t8 VALUES(0.0,0,2); - INSERT INTO t8 VALUES(0,0.0,3); - INSERT INTO t8 VALUES(0.0,0.0,4); - SELECT DISTINCT x, y FROM t8 ORDER BY z; - } -} {0 0 0.0 0} -do_test misc1-12.12 { - execsql { - SELECT min(z), max(z), count(z) FROM t8 GROUP BY x ORDER BY 1; - } -} {1 3 2 2 4 2} -do_test misc1-12.13 { - execsql { - SELECT min(z), max(z), count(z) FROM t8 GROUP BY y ORDER BY 1; - } -} {1 4 4} - -# There was a problem with realloc() in the OP_MemStore operation of -# the VDBE. A buffer was being reallocated but some pointers into -# the old copy of the buffer were not being moved over to the new copy. -# The following code tests for the problem. -# -ifcapable subquery { - do_test misc1-13.1 { - execsql { - CREATE TABLE t9(x,y); - INSERT INTO t9 VALUES('one',1); - INSERT INTO t9 VALUES('two',2); - INSERT INTO t9 VALUES('three',3); - INSERT INTO t9 VALUES('four',4); - INSERT INTO t9 VALUES('five',5); - INSERT INTO t9 VALUES('six',6); - INSERT INTO t9 VALUES('seven',7); - INSERT INTO t9 VALUES('eight',8); - INSERT INTO t9 VALUES('nine',9); - INSERT INTO t9 VALUES('ten',10); - INSERT INTO t9 VALUES('eleven',11); - SELECT y FROM t9 - WHERE x=(SELECT x FROM t9 WHERE y=1) - OR x=(SELECT x FROM t9 WHERE y=2) - OR x=(SELECT x FROM t9 WHERE y=3) - OR x=(SELECT x FROM t9 WHERE y=4) - OR x=(SELECT x FROM t9 WHERE y=5) - OR x=(SELECT x FROM t9 WHERE y=6) - OR x=(SELECT x FROM t9 WHERE y=7) - OR x=(SELECT x FROM t9 WHERE y=8) - OR x=(SELECT x FROM t9 WHERE y=9) - OR x=(SELECT x FROM t9 WHERE y=10) - OR x=(SELECT x FROM t9 WHERE y=11) - OR x=(SELECT x FROM t9 WHERE y=12) - OR x=(SELECT x FROM t9 WHERE y=13) - OR x=(SELECT x FROM t9 WHERE y=14) - ; - } - } {1 2 3 4 5 6 7 8 9 10 11} -} - -# Make sure a database connection still works after changing the -# working directory. -# -do_test misc1-14.1 { - file mkdir tempdir - cd tempdir - execsql {BEGIN} - file exists ./test.db-journal -} {0} -do_test misc1-14.2 { - execsql {UPDATE t1 SET a=0 WHERE 0} - file exists ../test.db-journal -} {1} -do_test misc1-14.3 { - cd .. - file delete tempdir - execsql {COMMIT} - file exists ./test.db-journal -} {0} - -# A failed create table should not leave the table in the internal -# data structures. Ticket #238. -# -do_test misc1-15.1 { - catchsql { - CREATE TABLE t10 AS SELECT c1; - } -} {1 {no such column: c1}} -do_test misc1-15.2 { - catchsql { - CREATE TABLE t10 AS SELECT 1; - } - # The bug in ticket #238 causes the statement above to fail with - # the error "table t10 alread exists" -} {0 {}} - -# Test for memory leaks when a CREATE TABLE containing a primary key -# fails. Ticket #249. -# -do_test misc1-16.1 { - catchsql {SELECT name FROM sqlite_master LIMIT 1} - catchsql { - CREATE TABLE test(a integer, primary key(a)); - } -} {0 {}} -do_test misc1-16.2 { - catchsql { - CREATE TABLE test(a integer, primary key(a)); - } -} {1 {table test already exists}} -do_test misc1-16.3 { - catchsql { - CREATE TABLE test2(a text primary key, b text, primary key(a,b)); - } -} {1 {table "test2" has more than one primary key}} -do_test misc1-16.4 { - execsql { - INSERT INTO test VALUES(1); - SELECT rowid, a FROM test; - } -} {1 1} -do_test misc1-16.5 { - execsql { - INSERT INTO test VALUES(5); - SELECT rowid, a FROM test; - } -} {1 1 5 5} -do_test misc1-16.6 { - execsql { - INSERT INTO test VALUES(NULL); - SELECT rowid, a FROM test; - } -} {1 1 5 5 6 6} - -ifcapable {trigger} { -# Ticket #333: Temp triggers that modify persistent tables. -# -do_test misc1-17.1 { - execsql { - BEGIN; - CREATE TABLE RealTable(TestID INTEGER PRIMARY KEY, TestString TEXT); - CREATE TEMP TABLE TempTable(TestID INTEGER PRIMARY KEY, TestString TEXT); - CREATE TEMP TRIGGER trigTest_1 AFTER UPDATE ON TempTable BEGIN - INSERT INTO RealTable(TestString) - SELECT new.TestString FROM TempTable LIMIT 1; - END; - INSERT INTO TempTable(TestString) VALUES ('1'); - INSERT INTO TempTable(TestString) VALUES ('2'); - UPDATE TempTable SET TestString = TestString + 1 WHERE TestID=1 OR TestId=2; - COMMIT; - SELECT TestString FROM RealTable ORDER BY 1; - } -} {2 3} -} - -finish_test diff --git a/sqlite/test/misc2.test b/sqlite/test/misc2.test deleted file mode 100644 index 85e4032..0000000 --- a/sqlite/test/misc2.test +++ /dev/null @@ -1,251 +0,0 @@ -# 2003 June 21 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# -# This file implements tests for miscellanous features that were -# left out of other test files. -# -# $Id: misc2.test,v 1.20 2005/01/21 04:25:47 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -ifcapable {trigger} { -# Test for ticket #360 -# -do_test misc2-1.1 { - catchsql { - CREATE TABLE FOO(bar integer); - CREATE TRIGGER foo_insert BEFORE INSERT ON foo BEGIN - SELECT CASE WHEN (NOT new.bar BETWEEN 0 AND 20) - THEN raise(rollback, 'aiieee') END; - END; - INSERT INTO foo(bar) VALUES (1); - } -} {0 {}} -do_test misc2-1.2 { - catchsql { - INSERT INTO foo(bar) VALUES (111); - } -} {1 aiieee} -} ;# endif trigger - -# Make sure ROWID works on a view and a subquery. Ticket #364 -# -do_test misc2-2.1 { - execsql { - CREATE TABLE t1(a,b,c); - INSERT INTO t1 VALUES(1,2,3); - CREATE TABLE t2(a,b,c); - INSERT INTO t2 VALUES(7,8,9); - } -} {} -ifcapable view { - ifcapable subquery { - do_test misc2-2.2 { - execsql { - SELECT rowid, * FROM (SELECT * FROM t1, t2); - } - } {{} 1 2 3 7 8 9} - } - do_test misc2-2.3 { - execsql { - CREATE VIEW v1 AS SELECT * FROM t1, t2; - SELECT rowid, * FROM v1; - } - } {{} 1 2 3 7 8 9} -} ;# ifcapable view - -# Check name binding precedence. Ticket #387 -# -do_test misc2-3.1 { - catchsql { - SELECT t1.b+t2.b AS a, t1.a, t2.a FROM t1, t2 WHERE a==10 - } -} {1 {ambiguous column name: a}} - -# Make sure 32-bit integer overflow is handled properly in queries. -# ticket #408 -# -do_test misc2-4.1 { - execsql { - INSERT INTO t1 VALUES(4000000000,'a','b'); - SELECT a FROM t1 WHERE a>1; - } -} {4000000000} -do_test misc2-4.2 { - execsql { - INSERT INTO t1 VALUES(2147483648,'b2','c2'); - INSERT INTO t1 VALUES(2147483647,'b3','c3'); - SELECT a FROM t1 WHERE a>2147483647; - } -} {4000000000 2147483648} -do_test misc2-4.3 { - execsql { - SELECT a FROM t1 WHERE a<2147483648; - } -} {1 2147483647} -do_test misc2-4.4 { - execsql { - SELECT a FROM t1 WHERE a<=2147483648; - } -} {1 2147483648 2147483647} -do_test misc2-4.5 { - execsql { - SELECT a FROM t1 WHERE a<10000000000; - } -} {1 4000000000 2147483648 2147483647} -do_test misc2-4.6 { - execsql { - SELECT a FROM t1 WHERE a<1000000000000 ORDER BY 1; - } -} {1 2147483647 2147483648 4000000000} - -# There were some issues with expanding a SrcList object using a call -# to sqliteSrcListAppend() if the SrcList had previously been duplicated -# using a call to sqliteSrcListDup(). Ticket #416. The following test -# makes sure the problem has been fixed. -# -ifcapable view { -do_test misc2-5.1 { - execsql { - CREATE TABLE x(a,b); - CREATE VIEW y AS - SELECT x1.b AS p, x2.b AS q FROM x AS x1, x AS x2 WHERE x1.a=x2.a; - CREATE VIEW z AS - SELECT y1.p, y2.p FROM y AS y1, y AS y2 WHERE y1.q=y2.q; - SELECT * from z; - } -} {} -} - -# Make sure we can open a database with an empty filename. What this -# does is store the database in a temporary file that is deleted when -# the database is closed. Ticket #432. -# -do_test misc2-6.1 { - db close - sqlite3 db {} - execsql { - CREATE TABLE t1(a,b); - INSERT INTO t1 VALUES(1,2); - SELECT * FROM t1; - } -} {1 2} - -# Make sure we get an error message (not a segfault) on an attempt to -# update a table from within the callback of a select on that same -# table. -# -do_test misc2-7.1 { - db close - file delete -force test.db - sqlite3 db test.db - execsql { - CREATE TABLE t1(x); - INSERT INTO t1 VALUES(1); - } - set rc [catch { - db eval {SELECT rowid FROM t1} {} { - db eval "DELETE FROM t1 WHERE rowid=$rowid" - } - } msg] - lappend rc $msg -} {1 {database table is locked}} -do_test misc2-7.2 { - set rc [catch { - db eval {SELECT rowid FROM t1} {} { - db eval "INSERT INTO t1 VALUES(3)" - } - } msg] - lappend rc $msg -} {1 {database table is locked}} -ifcapable memorydb { - do_test misc2-7.3 { - sqlite3 db :memory: - execsql { - CREATE TABLE t1(x); - INSERT INTO t1 VALUES(1); - } - set rc [catch { - db eval {SELECT rowid FROM t1} {} { - db eval "DELETE FROM t1 WHERE rowid=$rowid" - } - } msg] - lappend rc $msg - } {1 {database table is locked}} - do_test misc2-7.4 { - set rc [catch { - db eval {SELECT rowid FROM t1} {} { - db eval "INSERT INTO t1 VALUES(3)" - } - } msg] - lappend rc $msg - } {1 {database table is locked}} -} - -db close -file delete -force test.db -sqlite3 db test.db - -# Ticket #453. If the SQL ended with "-", the tokenizer was calling that -# an incomplete token, which caused problem. The solution was to just call -# it a minus sign. -# -do_test misc2-8.1 { - catchsql {-} -} {1 {near "-": syntax error}} - -# Ticket #513. Make sure the VDBE stack does not grow on a 3-way join. -# -do_test misc2-9.1 { - execsql { - BEGIN; - CREATE TABLE counts(n INTEGER PRIMARY KEY); - INSERT INTO counts VALUES(0); - INSERT INTO counts VALUES(1); - INSERT INTO counts SELECT n+2 FROM counts; - INSERT INTO counts SELECT n+4 FROM counts; - INSERT INTO counts SELECT n+8 FROM counts; - COMMIT; - - CREATE TEMP TABLE x AS - SELECT dim1.n, dim2.n, dim3.n - FROM counts AS dim1, counts AS dim2, counts AS dim3 - WHERE dim1.n<10 AND dim2.n<10 AND dim3.n<10; - - SELECT count(*) FROM x; - } -} {1000} -do_test misc2-9.2 { - execsql { - DROP TABLE x; - CREATE TEMP TABLE x AS - SELECT dim1.n, dim2.n, dim3.n - FROM counts AS dim1, counts AS dim2, counts AS dim3 - WHERE dim1.n>=6 AND dim2.n>=6 AND dim3.n>=6; - - SELECT count(*) FROM x; - } -} {1000} -do_test misc2-9.3 { - execsql { - DROP TABLE x; - CREATE TEMP TABLE x AS - SELECT dim1.n, dim2.n, dim3.n, dim4.n - FROM counts AS dim1, counts AS dim2, counts AS dim3, counts AS dim4 - WHERE dim1.n<5 AND dim2.n<5 AND dim3.n<5 AND dim4.n<5; - - SELECT count(*) FROM x; - } -} [expr 5*5*5*5] - -finish_test diff --git a/sqlite/test/misc3.test b/sqlite/test/misc3.test deleted file mode 100644 index cd76335..0000000 --- a/sqlite/test/misc3.test +++ /dev/null @@ -1,317 +0,0 @@ -# 2003 December 17 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# -# This file implements tests for miscellanous features that were -# left out of other test files. -# -# $Id: misc3.test,v 1.16 2005/01/21 03:12:16 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -ifcapable {integrityck} { - # Ticket #529. Make sure an ABORT does not damage the in-memory cache - # that will be used by subsequent statements in the same transaction. - # - do_test misc3-1.1 { - execsql { - CREATE TABLE t1(a UNIQUE,b); - INSERT INTO t1 - VALUES(1,'a23456789_b23456789_c23456789_d23456789_e23456789_'); - UPDATE t1 SET b=b||b; - UPDATE t1 SET b=b||b; - UPDATE t1 SET b=b||b; - UPDATE t1 SET b=b||b; - UPDATE t1 SET b=b||b; - INSERT INTO t1 VALUES(2,'x'); - UPDATE t1 SET b=substr(b,1,500); - BEGIN; - } - catchsql {UPDATE t1 SET a=CASE a WHEN 2 THEN 1 ELSE a END, b='y';} - execsql { - CREATE TABLE t2(x,y); - COMMIT; - PRAGMA integrity_check; - } - } ok -} -ifcapable {integrityck} { - do_test misc3-1.2 { - execsql { - DROP TABLE t1; - DROP TABLE t2; - } - ifcapable {vacuum} {execsql VACUUM} - execsql { - CREATE TABLE t1(a UNIQUE,b); - INSERT INTO t1 - VALUES(1,'a23456789_b23456789_c23456789_d23456789_e23456789_'); - INSERT INTO t1 SELECT a+1, b||b FROM t1; - INSERT INTO t1 SELECT a+2, b||b FROM t1; - INSERT INTO t1 SELECT a+4, b FROM t1; - INSERT INTO t1 SELECT a+8, b FROM t1; - INSERT INTO t1 SELECT a+16, b FROM t1; - INSERT INTO t1 SELECT a+32, b FROM t1; - INSERT INTO t1 SELECT a+64, b FROM t1; - BEGIN; - } - catchsql {UPDATE t1 SET a=CASE a WHEN 128 THEN 127 ELSE a END, b='';} - execsql { - INSERT INTO t1 VALUES(200,'hello out there'); - COMMIT; - PRAGMA integrity_check; - } - } ok -} - -# Tests of the sqliteAtoF() function in util.c -# -do_test misc3-2.1 { - execsql {SELECT 2e-25*0.5e25} -} 1.0 -do_test misc3-2.2 { - execsql {SELECT 2.0e-25*000000.500000000000000000000000000000e+00025} -} 1.0 -do_test misc3-2.3 { - execsql {SELECT 000000000002e-0000000025*0.5e25} -} 1.0 -do_test misc3-2.4 { - execsql {SELECT 2e-25*0.5e250} -} 1e+225 -do_test misc3-2.5 { - execsql {SELECT 2.0e-250*0.5e25} -} 1e-225 -do_test misc3-2.6 { - execsql {SELECT '-2.0e-127' * '-0.5e27'} -} 1e-100 -do_test misc3-2.7 { - execsql {SELECT '+2.0e-127' * '-0.5e27'} -} -1e-100 -do_test misc3-2.8 { - execsql {SELECT 2.0e-27 * '+0.5e+127'} -} 1e+100 -do_test misc3-2.9 { - execsql {SELECT 2.0e-27 * '+0.000005e+132'} -} 1e+100 - -# Ticket #522. Make sure integer overflow is handled properly in -# indices. -# -integrity_check misc3-3.1 -do_test misc3-3.2 { - execsql { - CREATE TABLE t2(a INT UNIQUE); - } -} {} -integrity_check misc3-3.2.1 -do_test misc3-3.3 { - execsql { - INSERT INTO t2 VALUES(2147483648); - } -} {} -integrity_check misc3-3.3.1 -do_test misc3-3.4 { - execsql { - INSERT INTO t2 VALUES(-2147483649); - } -} {} -integrity_check misc3-3.4.1 -do_test misc3-3.5 { - execsql { - INSERT INTO t2 VALUES(+2147483649); - } -} {} -integrity_check misc3-3.5.1 -do_test misc3-3.6 { - execsql { - INSERT INTO t2 VALUES(+2147483647); - INSERT INTO t2 VALUES(-2147483648); - INSERT INTO t2 VALUES(-2147483647); - INSERT INTO t2 VALUES(2147483646); - SELECT * FROM t2 ORDER BY a; - } -} {-2147483649 -2147483648 -2147483647 2147483646 2147483647 2147483648 2147483649} -do_test misc3-3.7 { - execsql { - SELECT * FROM t2 WHERE a>=-2147483648 ORDER BY a; - } -} {-2147483648 -2147483647 2147483646 2147483647 2147483648 2147483649} -do_test misc3-3.8 { - execsql { - SELECT * FROM t2 WHERE a>-2147483648 ORDER BY a; - } -} {-2147483647 2147483646 2147483647 2147483648 2147483649} -do_test misc3-3.9 { - execsql { - SELECT * FROM t2 WHERE a>-2147483649 ORDER BY a; - } -} {-2147483648 -2147483647 2147483646 2147483647 2147483648 2147483649} -do_test misc3-3.10 { - execsql { - SELECT * FROM t2 WHERE a>=0 AND a<2147483649 ORDER BY a DESC; - } -} {2147483648 2147483647 2147483646} -do_test misc3-3.11 { - execsql { - SELECT * FROM t2 WHERE a>=0 AND a<=2147483648 ORDER BY a DESC; - } -} {2147483648 2147483647 2147483646} -do_test misc3-3.12 { - execsql { - SELECT * FROM t2 WHERE a>=0 AND a<2147483648 ORDER BY a DESC; - } -} {2147483647 2147483646} -do_test misc3-3.13 { - execsql { - SELECT * FROM t2 WHERE a>=0 AND a<=2147483647 ORDER BY a DESC; - } -} {2147483647 2147483646} -do_test misc3-3.14 { - execsql { - SELECT * FROM t2 WHERE a>=0 AND a<2147483647 ORDER BY a DESC; - } -} {2147483646} - -# Ticket #565. A stack overflow is occurring when the subquery to the -# right of an IN operator contains many NULLs -# -do_test misc3-4.1 { - execsql { - CREATE TABLE t3(a INTEGER PRIMARY KEY, b); - INSERT INTO t3(b) VALUES('abc'); - INSERT INTO t3(b) VALUES('xyz'); - INSERT INTO t3(b) VALUES(NULL); - INSERT INTO t3(b) VALUES(NULL); - INSERT INTO t3(b) SELECT b||'d' FROM t3; - INSERT INTO t3(b) SELECT b||'e' FROM t3; - INSERT INTO t3(b) SELECT b||'f' FROM t3; - INSERT INTO t3(b) SELECT b||'g' FROM t3; - INSERT INTO t3(b) SELECT b||'h' FROM t3; - SELECT count(a), count(b) FROM t3; - } -} {128 64} -ifcapable subquery { -do_test misc3-4.2 { - execsql { - SELECT count(a) FROM t3 WHERE b IN (SELECT b FROM t3); - } - } {64} - do_test misc3-4.3 { - execsql { - SELECT count(a) FROM t3 WHERE b IN (SELECT b FROM t3 ORDER BY a+1); - } - } {64} -} - -# Ticket #601: Putting a left join inside "SELECT * FROM ()" -# gives different results that if the outer "SELECT * FROM ..." is omitted. -# -ifcapable subquery { - do_test misc3-5.1 { - execsql { - CREATE TABLE x1 (b, c); - INSERT INTO x1 VALUES('dog',3); - INSERT INTO x1 VALUES('cat',1); - INSERT INTO x1 VALUES('dog',4); - CREATE TABLE x2 (c, e); - INSERT INTO x2 VALUES(1,'one'); - INSERT INTO x2 VALUES(2,'two'); - INSERT INTO x2 VALUES(3,'three'); - INSERT INTO x2 VALUES(4,'four'); - SELECT x2.c AS c, e, b FROM x2 LEFT JOIN - (SELECT b, max(c)+0 AS c FROM x1 GROUP BY b) - USING(c); - } - } {1 one cat 2 two {} 3 three {} 4 four dog} - do_test misc3-5.2 { - execsql { - SELECT * FROM ( - SELECT x2.c AS c, e, b FROM x2 LEFT JOIN - (SELECT b, max(c)+0 AS c FROM x1 GROUP BY b) - USING(c) - ); - } - } {1 one cat 2 two {} 3 three {} 4 four dog} -} - -ifcapable {explain} { - # Ticket #626: make sure EXPLAIN prevents BEGIN and COMMIT from working. - # - do_test misc3-6.1 { - execsql {EXPLAIN BEGIN} - catchsql {BEGIN} - } {0 {}} - do_test misc3-6.2 { - execsql {EXPLAIN COMMIT} - catchsql {COMMIT} - } {0 {}} - do_test misc3-6.3 { - execsql {BEGIN; EXPLAIN ROLLBACK} - catchsql {ROLLBACK} - } {0 {}} -} - -ifcapable {trigger} { -# Ticket #640: vdbe stack overflow with a LIMIT clause on a SELECT inside -# of a trigger. -# -do_test misc3-7.1 { - execsql { - BEGIN; - CREATE TABLE y1(a); - CREATE TABLE y2(b); - CREATE TABLE y3(c); - CREATE TRIGGER r1 AFTER DELETE ON y1 FOR EACH ROW BEGIN - INSERT INTO y3(c) SELECT b FROM y2 ORDER BY b LIMIT 1; - END; - INSERT INTO y1 VALUES(1); - INSERT INTO y1 VALUES(2); - INSERT INTO y1 SELECT a+2 FROM y1; - INSERT INTO y1 SELECT a+4 FROM y1; - INSERT INTO y1 SELECT a+8 FROM y1; - INSERT INTO y1 SELECT a+16 FROM y1; - INSERT INTO y2 SELECT a FROM y1; - COMMIT; - SELECT count(*) FROM y1; - } -} 32 -do_test misc3-7.2 { - execsql { - DELETE FROM y1; - SELECT count(*) FROM y1; - } -} 0 -do_test misc3-7.3 { - execsql { - SELECT count(*) FROM y3; - } -} 32 -} ;# endif trigger - -# Ticket #668: VDBE stack overflow occurs when the left-hand side -# of an IN expression is NULL and the result is used as an integer, not -# as a jump. -# -ifcapable subquery { - do_test misc-8.1 { - execsql { - SELECT count(CASE WHEN b IN ('abc','xyz') THEN 'x' END) FROM t3 - } - } {2} - do_test misc-8.2 { - execsql { - SELECT count(*) FROM t3 WHERE 1+(b IN ('abc','xyz'))==2 - } - } {2} -} - -finish_test diff --git a/sqlite/test/misc4.test b/sqlite/test/misc4.test deleted file mode 100644 index cad97ff..0000000 --- a/sqlite/test/misc4.test +++ /dev/null @@ -1,177 +0,0 @@ -# 2004 Jun 27 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# -# This file implements tests for miscellanous features that were -# left out of other test files. -# -# $Id: misc4.test,v 1.15 2005/01/30 09:17:59 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Prepare a statement that will create a temporary table. Then do -# a rollback. Then try to execute the prepared statement. -# -do_test misc4-1.1 { - db close - set DB [sqlite3 db test.db] - execsql { - CREATE TABLE t1(x); - INSERT INTO t1 VALUES(1); - } -} {} -do_test misc4-1.2 { - set sql {CREATE TEMP TABLE t2 AS SELECT * FROM t1} - set stmt [sqlite3_prepare $DB $sql -1 TAIL] - execsql { - BEGIN; - CREATE TABLE t3(a,b,c); - INSERT INTO t1 SELECT * FROM t1; - ROLLBACK; - } -} {} -do_test misc4-1.3 { - sqlite3_step $stmt -} SQLITE_DONE -do_test misc4-1.4 { - execsql { - SELECT * FROM temp.t2; - } -} {1} - -# Drop the temporary table, then rerun the prepared statement to -# recreate it again. This recreates ticket #807. -# -do_test misc4-1.5 { - execsql {DROP TABLE t2} - sqlite3_reset $stmt - sqlite3_step $stmt -} {SQLITE_ERROR} -do_test misc4-1.6 { - sqlite3_finalize $stmt -} {SQLITE_SCHEMA} - -# Prepare but do not execute various CREATE statements. Then before -# those statements are executed, try to use the tables, indices, views, -# are triggers that were created. -# -do_test misc4-2.1 { - set stmt [sqlite3_prepare $DB {CREATE TABLE t3(x);} -1 TAIL] - catchsql { - INSERT INTO t3 VALUES(1); - } -} {1 {no such table: t3}} -do_test misc4-2.2 { - sqlite3_step $stmt -} SQLITE_DONE -do_test misc4-2.3 { - sqlite3_finalize $stmt -} SQLITE_OK -do_test misc4-2.4 { - catchsql { - INSERT INTO t3 VALUES(1); - } -} {0 {}} - -# Ticket #966 -# -ifcapable compound { -do_test misc4-3.1 { - execsql { - CREATE TABLE Table1(ID integer primary key, Value TEXT); - INSERT INTO Table1 VALUES(1, 'x'); - CREATE TABLE Table2(ID integer NOT NULL, Value TEXT); - INSERT INTO Table2 VALUES(1, 'z'); - INSERT INTO Table2 VALUES (1, 'a'); - SELECT ID, Value FROM Table1 - UNION SELECT ID, max(Value) FROM Table2 GROUP BY 1,2 - ORDER BY 1, 2; - } -} {{} {} 1 x 1 z} -} ;# ifcapable compound - -# Ticket #1047. Make sure column types are preserved in subqueries. -# -ifcapable subquery { - do_test misc4-4.1 { - execsql { - create table a(key varchar, data varchar); - create table b(key varchar, period integer); - insert into a values('01','data01'); - insert into a values('+1','data+1'); - - insert into b values ('01',1); - insert into b values ('01',2); - insert into b values ('+1',3); - insert into b values ('+1',4); - - select a.*, x.* - from a, (select key,sum(period) from b group by key) as x - where a.key=x.key; - } - } {01 data01 01 3.0 +1 data+1 +1 7.0} - - # This test case tests the same property as misc4-4.1, but it is - # a bit smaller which makes it easier to work with while debugging. - do_test misc4-4.2 { - execsql { - CREATE TABLE ab(a TEXT, b TEXT); - INSERT INTO ab VALUES('01', '1'); - } - execsql { - select * from ab, (select b from ab) as x where x.b = ab.a; - } - } {} -} - - -# Ticket #1036. When creating tables from a SELECT on a view, use the -# short names of columns. -# -ifcapable view { - do_test misc4-5.1 { - execsql { - create table t4(a,b); - create table t5(a,c); - insert into t4 values (1,2); - insert into t5 values (1,3); - create view myview as select t4.a a from t4 inner join t5 on t4.a=t5.a; - create table problem as select * from myview; - } - execsql2 { - select * FROM problem; - } - } {a 1} - do_test misc4-5.2 { - execsql2 { - create table t6 as select * from t4, t5; - select * from t6; - } - } {a 1 b 2 a:1 1 c 3} -} - -# Ticket #1086 -do_test misc4-6.1 { - execsql { - CREATE TABLE abc(a); - INSERT INTO abc VALUES(1); - CREATE TABLE def(d, e, f, PRIMARY KEY(d, e)); - } -} {} -do_test misc4-6.2 { - execsql { - SELECT a FROM abc LEFT JOIN def ON (abc.a=def.d); - } -} {1} - -finish_test - diff --git a/sqlite/test/misuse.test b/sqlite/test/misuse.test deleted file mode 100644 index 8d96af6..0000000 --- a/sqlite/test/misuse.test +++ /dev/null @@ -1,207 +0,0 @@ -# 2002 May 10 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# -# This file implements tests for the SQLITE_MISUSE detection logic. -# This test file leaks memory and file descriptors. -# -# $Id: misuse.test,v 1.10 2005/01/24 10:26:00 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -proc catchsql2 {sql} { - set r [ - catch { - set res [list] - db eval $sql data { - if { $res==[list] } { - foreach f $data(*) {lappend res $f} - } - foreach f $data(*) {lappend res $data($f)} - } - set res - } msg - ] - lappend r $msg -} - - -# Make sure the test logic works -# -do_test misuse-1.1 { - db close - catch {file delete -force test2.db} - catch {file delete -force test2.db-journal} - set ::DB [sqlite3 db test2.db] - execsql { - CREATE TABLE t1(a,b); - INSERT INTO t1 VALUES(1,2); - } - catchsql2 { - SELECT * FROM t1 - } -} {0 {a b 1 2}} -do_test misuse-1.2 { - catchsql2 { - SELECT x_coalesce(NULL,a) AS 'xyz' FROM t1 - } -} {1 {no such function: x_coalesce}} -do_test misuse-1.3 { - sqlite3_create_function $::DB - catchsql2 { - SELECT x_coalesce(NULL,a) AS 'xyz' FROM t1 - } -} {0 {xyz 1}} - -# Use the x_sqlite_exec() SQL function to simulate the effect of two -# threads trying to use the same database at the same time. -# -# It used to be prohibited to invoke sqlite_exec() from within a function, -# but that has changed. The following tests used to cause errors but now -# they do not. -# -ifcapable {utf16} { - do_test misuse-1.4 { - catchsql2 { - SELECT x_sqlite_exec('SELECT * FROM t1') AS xyz; - } - } {0 {xyz {1 2}}} -} -do_test misuse-1.5 { - catchsql2 {SELECT * FROM t1} -} {0 {a b 1 2}} -do_test misuse-1.6 { - catchsql { - SELECT * FROM t1 - } -} {0 {1 2}} - -# Attempt to register a new SQL function while an sqlite_exec() is active. -# -do_test misuse-2.1 { - db close - set ::DB [sqlite3 db test2.db] - execsql { - SELECT * FROM t1 - } -} {1 2} -do_test misuse-2.2 { - catchsql2 {SELECT * FROM t1} -} {0 {a b 1 2}} - -# We used to disallow creating new function from within an exec(). -# But now this is acceptable. -do_test misuse-2.3 { - set v [catch { - db eval {SELECT * FROM t1} {} { - sqlite3_create_function $::DB - } - } msg] - lappend v $msg -} {0 {}} -do_test misuse-2.4 { - catchsql2 {SELECT * FROM t1} -} {0 {a b 1 2}} -do_test misuse-2.5 { - catchsql { - SELECT * FROM t1 - } -} {0 {1 2}} - -# Attempt to register a new SQL aggregate while an sqlite_exec() is active. -# -do_test misuse-3.1 { - db close - set ::DB [sqlite3 db test2.db] - execsql { - SELECT * FROM t1 - } -} {1 2} -do_test misuse-3.2 { - catchsql2 {SELECT * FROM t1} -} {0 {a b 1 2}} - -# We used to disallow creating new function from within an exec(). -# But now this is acceptable. -do_test misuse-3.3 { - set v [catch { - db eval {SELECT * FROM t1} {} { - sqlite3_create_aggregate $::DB - } - } msg] - lappend v $msg -} {0 {}} -do_test misuse-3.4 { - catchsql2 {SELECT * FROM t1} -} {0 {a b 1 2}} -do_test misuse-3.5 { - catchsql { - SELECT * FROM t1 - } -} {0 {1 2}} - -# Attempt to close the database from an sqlite_exec callback. -# -# Update for v3: The db cannot be closed because there are active -# VMs. The sqlite3_close call would return SQLITE_BUSY. -do_test misuse-4.1 { - db close - set ::DB [sqlite3 db test2.db] - execsql { - SELECT * FROM t1 - } -} {1 2} -do_test misuse-4.2 { - catchsql2 {SELECT * FROM t1} -} {0 {a b 1 2}} -do_test misuse-4.3 { - set v [catch { - db eval {SELECT * FROM t1} {} { - set r [sqlite3_close $::DB] - } - } msg] - lappend v $msg $r -} {0 {} SQLITE_BUSY} -do_test misuse-4.4 { - # Flush the TCL statement cache here, otherwise the sqlite3_close() will - # fail because there are still un-finalized() VDBEs. - db cache flush - sqlite3_close $::DB - catchsql2 {SELECT * FROM t1} -} {1 {library routine called out of sequence}} -do_test misuse-4.5 { - catchsql { - SELECT * FROM t1 - } -} {1 {library routine called out of sequence}} - -# Attempt to use a database after it has been closed. -# -do_test misuse-5.1 { - db close - set ::DB [sqlite3 db test2.db] - execsql { - SELECT * FROM t1 - } -} {1 2} -do_test misuse-5.2 { - catchsql2 {SELECT * FROM t1} -} {0 {a b 1 2}} -do_test misuse-5.3 { - db close - set r [catch { - sqlite3_prepare $::DB {SELECT * FROM t1} -1 TAIL - } msg] - lappend r $msg -} {1 {(21) library routine called out of sequence}} - -finish_test diff --git a/sqlite/test/null.test b/sqlite/test/null.test deleted file mode 100644 index 0693f29..0000000 --- a/sqlite/test/null.test +++ /dev/null @@ -1,242 +0,0 @@ -# 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 implements regression tests for SQLite library. -# -# This file implements tests for proper treatment of the special -# value NULL. -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Create a table and some data to work with. -# -do_test null-1.0 { - execsql { - begin; - create table t1(a,b,c); - insert into t1 values(1,0,0); - insert into t1 values(2,0,1); - insert into t1 values(3,1,0); - insert into t1 values(4,1,1); - insert into t1 values(5,null,0); - insert into t1 values(6,null,1); - insert into t1 values(7,null,null); - commit; - select * from t1; - } -} {1 0 0 2 0 1 3 1 0 4 1 1 5 {} 0 6 {} 1 7 {} {}} - -# Check for how arithmetic expressions handle NULL -# -do_test null-1.1 { - execsql { - select ifnull(a+b,99) from t1; - } -} {1 2 4 5 99 99 99} -do_test null-1.2 { - execsql { - select ifnull(b*c,99) from t1; - } -} {0 0 0 1 99 99 99} - -# Check to see how the CASE expression handles NULL values. The -# first WHEN for which the test expression is TRUE is selected. -# FALSE and UNKNOWN test expressions are skipped. -# -do_test null-2.1 { - execsql { - select ifnull(case when b<>0 then 1 else 0 end, 99) from t1; - } -} {0 0 1 1 0 0 0} -do_test null-2.2 { - execsql { - select ifnull(case when not b<>0 then 1 else 0 end, 99) from t1; - } -} {1 1 0 0 0 0 0} -do_test null-2.3 { - execsql { - select ifnull(case when b<>0 and c<>0 then 1 else 0 end, 99) from t1; - } -} {0 0 0 1 0 0 0} -do_test null-2.4 { - execsql { - select ifnull(case when not (b<>0 and c<>0) then 1 else 0 end, 99) from t1; - } -} {1 1 1 0 1 0 0} -do_test null-2.5 { - execsql { - select ifnull(case when b<>0 or c<>0 then 1 else 0 end, 99) from t1; - } -} {0 1 1 1 0 1 0} -do_test null-2.6 { - execsql { - select ifnull(case when not (b<>0 or c<>0) then 1 else 0 end, 99) from t1; - } -} {1 0 0 0 0 0 0} -do_test null-2.7 { - execsql { - select ifnull(case b when c then 1 else 0 end, 99) from t1; - } -} {1 0 0 1 0 0 0} -do_test null-2.8 { - execsql { - select ifnull(case c when b then 1 else 0 end, 99) from t1; - } -} {1 0 0 1 0 0 0} - -# Check to see that NULL values are ignored in aggregate functions. -# -do_test null-3.1 { - execsql { - select count(*), count(b), count(c), sum(b), sum(c), - avg(b), avg(c), min(b), max(b) from t1; - } -} {7 4 6 2.0 3.0 0.5 0.5 0 1} - -# Check to see how WHERE clauses handle NULL values. A NULL value -# is the same as UNKNOWN. The WHERE clause should only select those -# rows that are TRUE. FALSE and UNKNOWN rows are rejected. -# -do_test null-4.1 { - execsql { - select a from t1 where b<10 - } -} {1 2 3 4} -do_test null-4.2 { - execsql { - select a from t1 where not b>10 - } -} {1 2 3 4} -do_test null-4.3 { - execsql { - select a from t1 where b<10 or c=1; - } -} {1 2 3 4 6} -do_test null-4.4 { - execsql { - select a from t1 where b<10 and c=1; - } -} {2 4} -do_test null-4.5 { - execsql { - select a from t1 where not (b<10 and c=1); - } -} {1 3 5} - -# The DISTINCT keyword on a SELECT statement should treat NULL values -# as distinct -# -do_test null-5.1 { - execsql { - select distinct b from t1 order by b; - } -} {{} 0 1} - -# A UNION to two queries should treat NULL values -# as distinct -# -ifcapable compound { -do_test null-6.1 { - execsql { - select b from t1 union select c from t1 order by c; - } -} {{} 0 1} -} ;# ifcapable compound - -# The UNIQUE constraint only applies to non-null values -# -do_test null-7.1 { - execsql { - create table t2(a, b unique on conflict ignore); - insert into t2 values(1,1); - insert into t2 values(2,null); - insert into t2 values(3,null); - insert into t2 values(4,1); - select a from t2; - } -} {1 2 3} -do_test null-7.2 { - execsql { - create table t3(a, b, c, unique(b,c) on conflict ignore); - insert into t3 values(1,1,1); - insert into t3 values(2,null,1); - insert into t3 values(3,null,1); - insert into t3 values(4,1,1); - select a from t3; - } -} {1 2 3} - -# Ticket #461 - Make sure nulls are handled correctly when doing a -# lookup using an index. -# -do_test null-8.1 { - execsql { - CREATE TABLE t4(x,y); - INSERT INTO t4 VALUES(1,11); - INSERT INTO t4 VALUES(2,NULL); - SELECT x FROM t4 WHERE y=NULL; - } -} {} -ifcapable subquery { - do_test null-8.2 { - execsql { - SELECT x FROM t4 WHERE y IN (33,NULL); - } - } {} -} -do_test null-8.3 { - execsql { - SELECT x FROM t4 WHERE y<33 ORDER BY x; - } -} {1} -do_test null-8.4 { - execsql { - SELECT x FROM t4 WHERE y>6 ORDER BY x; - } -} {1} -do_test null-8.5 { - execsql { - SELECT x FROM t4 WHERE y!=33 ORDER BY x; - } -} {1} -do_test null-8.11 { - execsql { - CREATE INDEX t4i1 ON t4(y); - SELECT x FROM t4 WHERE y=NULL; - } -} {} -ifcapable subquery { - do_test null-8.12 { - execsql { - SELECT x FROM t4 WHERE y IN (33,NULL); - } - } {} -} -do_test null-8.13 { - execsql { - SELECT x FROM t4 WHERE y<33 ORDER BY x; - } -} {1} -do_test null-8.14 { - execsql { - SELECT x FROM t4 WHERE y>6 ORDER BY x; - } -} {1} -do_test null-8.15 { - execsql { - SELECT x FROM t4 WHERE y!=33 ORDER BY x; - } -} {1} - - - -finish_test diff --git a/sqlite/test/pager.test b/sqlite/test/pager.test deleted file mode 100644 index a733167..0000000 --- a/sqlite/test/pager.test +++ /dev/null @@ -1,528 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this script is page cache subsystem. -# -# $Id: pager.test,v 1.23 2005/01/22 03:39:39 danielk1977 Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -if {[info commands pager_open]!=""} { -db close - -# Basic sanity check. Open and close a pager. -# -do_test pager-1.0 { - catch {file delete -force ptf1.db} - catch {file delete -force ptf1.db-journal} - set v [catch { - set ::p1 [pager_open ptf1.db 10] - } msg] -} {0} -do_test pager-1.1 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0} -do_test pager-1.2 { - pager_pagecount $::p1 -} {0} -do_test pager-1.3 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0} -do_test pager-1.4 { - pager_close $::p1 -} {} - -# Try to write a few pages. -# -do_test pager-2.1 { - set v [catch { - set ::p1 [pager_open ptf1.db 10] - } msg] -} {0} -#do_test pager-2.2 { -# set v [catch { -# set ::g1 [page_get $::p1 0] -# } msg] -# lappend v $msg -#} {1 SQLITE_ERROR} -do_test pager-2.3.1 { - set ::gx [page_lookup $::p1 1] -} {} -do_test pager-2.3.2 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0} -do_test pager-2.3.3 { - set v [catch { - set ::g1 [page_get $::p1 1] - } msg] - if {$v} {lappend v $msg} - set v -} {0} -do_test pager-2.3.3 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.3.4 { - set ::gx [page_lookup $::p1 1] - expr {$::gx!=""} -} {1} -do_test pager-2.3.5 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.3.6 { - expr {$::g1==$::gx} -} {1} -do_test pager-2.3.7 { - page_unref $::gx - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.4 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.5 { - pager_pagecount $::p1 -} {0} -do_test pager-2.6 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.7 { - page_number $::g1 -} {1} -do_test pager-2.8 { - page_read $::g1 -} {} -do_test pager-2.9 { - page_unref $::g1 -} {} -do_test pager-2.10 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 1 ovfl 0} -do_test pager-2.11 { - set ::g1 [page_get $::p1 1] - expr {$::g1!=0} -} {1} -do_test pager-2.12 { - page_number $::g1 -} {1} -do_test pager-2.13 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 2 ovfl 0} -do_test pager-2.14 { - set v [catch { - page_write $::g1 "Page-One" - } msg] - lappend v $msg -} {0 {}} -do_test pager-2.15 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 1 state 2 err 0 hit 0 miss 2 ovfl 0} -do_test pager-2.16 { - page_read $::g1 -} {Page-One} -do_test pager-2.17 { - set v [catch { - pager_commit $::p1 - } msg] - lappend v $msg -} {0 {}} -do_test pager-2.20 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size -1 state 1 err 0 hit 1 miss 2 ovfl 0} -do_test pager-2.19 { - pager_pagecount $::p1 -} {1} -do_test pager-2.21 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 1 state 1 err 0 hit 1 miss 2 ovfl 0} -do_test pager-2.22 { - page_unref $::g1 -} {} -do_test pager-2.23 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 1 miss 2 ovfl 0} -do_test pager-2.24 { - set v [catch { - page_get $::p1 1 - } ::g1] - if {$v} {lappend v $::g1} - set v -} {0} -do_test pager-2.25 { - page_read $::g1 -} {Page-One} -do_test pager-2.26 { - set v [catch { - page_write $::g1 {page-one} - } msg] - lappend v $msg -} {0 {}} -do_test pager-2.27 { - page_read $::g1 -} {page-one} -do_test pager-2.28 { - set v [catch { - pager_rollback $::p1 - } msg] - lappend v $msg -} {0 {}} -do_test pager-2.29 { - page_unref $::g1 - set ::g1 [page_get $::p1 1] - page_read $::g1 -} {Page-One} -do_test pager-2.99 { - pager_close $::p1 -} {} - -do_test pager-3.1 { - set v [catch { - set ::p1 [pager_open ptf1.db 15] - } msg] - if {$v} {lappend v $msg} - set v -} {0} -do_test pager-3.2 { - pager_pagecount $::p1 -} {1} -do_test pager-3.3 { - set v [catch { - set ::g(1) [page_get $::p1 1] - } msg] - if {$v} {lappend v $msg} - set v -} {0} -do_test pager-3.4 { - page_read $::g(1) -} {Page-One} -do_test pager-3.5 { - for {set i 2} {$i<=20} {incr i} { - set gx [page_get $::p1 $i] - page_write $gx "Page-$i" - page_unref $gx - } - pager_commit $::p1 -} {} -for {set i 2} {$i<=20} {incr i} { - do_test pager-3.6.[expr {$i-1}] [subst { - set gx \[page_get $::p1 $i\] - set v \[page_read \$gx\] - page_unref \$gx - set v - }] "Page-$i" -} -for {set i 1} {$i<=20} {incr i} { - regsub -all CNT { - set ::g1 [page_get $::p1 CNT] - set ::g2 [page_get $::p1 CNT] - set ::vx [page_read $::g2] - expr {$::g1==$::g2} - } $i body; - do_test pager-3.7.$i.1 $body {1} - regsub -all CNT { - page_unref $::g2 - set vy [page_read $::g1] - expr {$vy==$::vx} - } $i body; - do_test pager-3.7.$i.2 $body {1} - regsub -all CNT { - page_unref $::g1 - set gx [page_get $::p1 CNT] - set vy [page_read $gx] - page_unref $gx - expr {$vy==$::vx} - } $i body; - do_test pager-3.7.$i.3 $body {1} -} -do_test pager-3.99 { - pager_close $::p1 -} {} - -# tests of the checkpoint mechanism and api -# -do_test pager-4.0 { - set v [catch { - file delete -force ptf1.db - set ::p1 [pager_open ptf1.db 15] - } msg] - if {$v} {lappend v $msg} - set v -} {0} -do_test pager-4.1 { - set g1 [page_get $::p1 1] - page_write $g1 "Page-1 v0" - for {set i 2} {$i<=20} {incr i} { - set gx [page_get $::p1 $i] - page_write $gx "Page-$i v0" - page_unref $gx - } - pager_commit $::p1 -} {} -for {set i 1} {$i<=20} {incr i} { - do_test pager-4.2.$i { - set gx [page_get $p1 $i] - set v [page_read $gx] - page_unref $gx - set v - } "Page-$i v0" -} -do_test pager-4.3 { - lrange [pager_stats $::p1] 0 1 -} {ref 1} -do_test pager-4.4 { - lrange [pager_stats $::p1] 8 9 -} {state 1} - -for {set i 1} {$i<20} {incr i} { - do_test pager-4.5.$i.0 { - set res {} - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - set value [page_read $gx] - page_unref $gx - set shouldbe "Page-$j v[expr {$i-1}]" - if {$value!=$shouldbe} { - lappend res $value $shouldbe - } - } - set res - } {} - do_test pager-4.5.$i.1 { - page_write $g1 "Page-1 v$i" - lrange [pager_stats $p1] 8 9 - } {state 2} - do_test pager-4.5.$i.2 { - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - page_write $gx "Page-$j v$i" - page_unref $gx - if {$j==$i} { - pager_stmt_begin $p1 - } - } - } {} - do_test pager-4.5.$i.3 { - set res {} - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - set value [page_read $gx] - page_unref $gx - set shouldbe "Page-$j v$i" - if {$value!=$shouldbe} { - lappend res $value $shouldbe - } - } - set res - } {} - do_test pager-4.5.$i.4 { - pager_rollback $p1 - set res {} - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - set value [page_read $gx] - page_unref $gx - set shouldbe "Page-$j v[expr {$i-1}]" - if {$value!=$shouldbe} { - lappend res $value $shouldbe - } - } - set res - } {} - do_test pager-4.5.$i.5 { - page_write $g1 "Page-1 v$i" - lrange [pager_stats $p1] 8 9 - } {state 2} - do_test pager-4.5.$i.6 { - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - page_write $gx "Page-$j v$i" - page_unref $gx - if {$j==$i} { - pager_stmt_begin $p1 - } - } - } {} - do_test pager-4.5.$i.7 { - pager_stmt_rollback $p1 - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - set value [page_read $gx] - page_unref $gx - if {$j<=$i || $i==1} { - set shouldbe "Page-$j v$i" - } else { - set shouldbe "Page-$j v[expr {$i-1}]" - } - if {$value!=$shouldbe} { - lappend res $value $shouldbe - } - } - set res - } {} - do_test pager-4.5.$i.8 { - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - page_write $gx "Page-$j v$i" - page_unref $gx - if {$j==$i} { - pager_stmt_begin $p1 - } - } - } {} - do_test pager-4.5.$i.9 { - pager_stmt_commit $p1 - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - set value [page_read $gx] - page_unref $gx - set shouldbe "Page-$j v$i" - if {$value!=$shouldbe} { - lappend res $value $shouldbe - } - } - set res - } {} - do_test pager-4.5.$i.10 { - pager_commit $p1 - lrange [pager_stats $p1] 8 9 - } {state 1} -} - -# Test that nothing bad happens when sqlite3pager_set_cachesize() is -# called with a negative argument. -do_test pager-4.6.1 { - pager_close [pager_open ptf2.db -15] -} {} - -# Test truncate on an in-memory database is Ok. -ifcapable memorydb { - do_test pager-4.6.2 { - set ::p2 [pager_open :memory: 10] - pager_truncate $::p2 5 - } {} - do_test pager-4.6.3 { - for {set i 1} {$i<5} {incr i} { - set p [page_get $::p2 $i] - page_write $p "Page $i" - page_unref $p - pager_commit $::p2 - } - pager_truncate $::p2 3 - } {} - do_test pager-4.6.4 { - pager_close $::p2 - } {} -} - -do_test pager-4.99 { - pager_close $::p1 -} {} - - - - file delete -force ptf1.db - -} ;# end if( not mem: and has pager_open command ); - -if 0 { -# Ticket #615: an assertion fault inside the pager. It is a benign -# fault, but we might as well test for it. -# -do_test pager-5.1 { - sqlite3 db test.db - execsql { - BEGIN; - CREATE TABLE t1(x); - PRAGMA synchronous=off; - COMMIT; - } -} {} -} - -# The following tests cover rolling back hot journal files. -# They can't be run on windows because the windows version of -# SQLite holds a mandatory exclusive lock on journal files it has open. -# -if {$tcl_platform(platform)!="windows"} { -do_test pager-6.1 { - file delete -force test2.db - file delete -force test2.db-journal - sqlite3 db2 test2.db - execsql { - PRAGMA synchronous = 0; - CREATE TABLE abc(a, b, c); - INSERT INTO abc VALUES(1, 2, randstr(200,200)); - INSERT INTO abc VALUES(1, 2, randstr(200,200)); - INSERT INTO abc VALUES(1, 2, randstr(200,200)); - INSERT INTO abc VALUES(1, 2, randstr(200,200)); - INSERT INTO abc VALUES(1, 2, randstr(200,200)); - INSERT INTO abc VALUES(1, 2, randstr(200,200)); - INSERT INTO abc VALUES(1, 2, randstr(200,200)); - INSERT INTO abc VALUES(1, 2, randstr(200,200)); - INSERT INTO abc VALUES(1, 2, randstr(200,200)); - BEGIN; - UPDATE abc SET c = randstr(200,200); - } db2 - copy_file test2.db test.db - copy_file test2.db-journal test.db-journal - - set f [open test.db-journal a] - fconfigure $f -encoding binary - seek $f [expr [file size test.db-journal] - 1032] start - puts -nonewline $f "\00\00\00\00" - close $f - - sqlite3 db test.db - execsql { - SELECT sql FROM sqlite_master - } -} {{CREATE TABLE abc(a, b, c)}} - -do_test pager-6.2 { - copy_file test2.db test.db - copy_file test2.db-journal test.db-journal - - set f [open test.db-journal a] - fconfigure $f -encoding binary - seek $f [expr [file size test.db-journal] - 1032] start - puts -nonewline $f "\00\00\00\FF" - close $f - - sqlite3 db test.db - execsql { - SELECT sql FROM sqlite_master - } -} {{CREATE TABLE abc(a, b, c)}} - -do_test pager-6.3 { - copy_file test2.db test.db - copy_file test2.db-journal test.db-journal - - set f [open test.db-journal a] - fconfigure $f -encoding binary - seek $f [expr [file size test.db-journal] - 4] start - puts -nonewline $f "\00\00\00\00" - close $f - - sqlite3 db test.db - execsql { - SELECT sql FROM sqlite_master - } -} {{CREATE TABLE abc(a, b, c)}} - -do_test pager-6.4 { - db2 close -} {} -} -finish_test - - - diff --git a/sqlite/test/pager2.test b/sqlite/test/pager2.test deleted file mode 100644 index 3907257..0000000 --- a/sqlite/test/pager2.test +++ /dev/null @@ -1,408 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this script is page cache subsystem. -# -# $Id: pager2.test,v 1.5 2004/11/22 05:26:28 danielk1977 Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Don't run this test file if the pager test interface [pager_open] is not -# available, or the library was compiled without in-memory database support. -# -if {[info commands pager_open]!=""} { -ifcapable memorydb { -db close - -# Basic sanity check. Open and close a pager. -# -do_test pager2-1.0 { - set v [catch { - set ::p1 [pager_open :memory: 10] - } msg] -} {0} -do_test pager2-1.1 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size 0 state 0 err 0 hit 0 miss 0 ovfl 0} -do_test pager2-1.2 { - pager_pagecount $::p1 -} {0} -do_test pager2-1.3 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size 0 state 0 err 0 hit 0 miss 0 ovfl 0} -do_test pager2-1.4 { - pager_close $::p1 -} {} - -# Try to write a few pages. -# -do_test pager2-2.1 { - set v [catch { - set ::p1 [pager_open :memory: 10] - } msg] -} {0} -#do_test pager2-2.2 { -# set v [catch { -# set ::g1 [page_get $::p1 0] -# } msg] -# lappend v $msg -#} {1 SQLITE_ERROR} -do_test pager2-2.3.1 { - set ::gx [page_lookup $::p1 1] -} {} -do_test pager2-2.3.2 { - pager_stats $::p1 -} {ref 0 page 0 max 10 size 0 state 0 err 0 hit 0 miss 0 ovfl 0} -do_test pager2-2.3.3 { - set v [catch { - set ::g1 [page_get $::p1 1] - } msg] - if {$v} {lappend v $msg} - set v -} {0} -do_test pager2-2.3.3 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager2-2.3.4 { - set ::gx [page_lookup $::p1 1] - expr {$::gx!=""} -} {1} -do_test pager2-2.3.5 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager2-2.3.6 { - expr {$::g1==$::gx} -} {1} -do_test pager2-2.3.7 { - page_unref $::gx - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager2-2.4 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager2-2.5 { - pager_pagecount $::p1 -} {0} -do_test pager2-2.6 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager2-2.7 { - page_number $::g1 -} {1} -do_test pager2-2.8 { - page_read $::g1 -} {} -do_test pager2-2.9 { - page_unref $::g1 -} {} -do_test pager2-2.10 { - pager_stats $::p1 -} {ref 0 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} -do_test pager2-2.11 { - set ::g1 [page_get $::p1 1] - expr {$::g1!=0} -} {1} -do_test pager2-2.12 { - page_number $::g1 -} {1} -do_test pager2-2.13 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 1 miss 1 ovfl 0} -do_test pager2-2.14 { - set v [catch { - page_write $::g1 "Page-One" - } msg] - lappend v $msg -} {0 {}} -do_test pager2-2.15 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 1 state 4 err 0 hit 1 miss 1 ovfl 0} -do_test pager2-2.16 { - page_read $::g1 -} {Page-One} -do_test pager2-2.17 { - set v [catch { - pager_commit $::p1 - } msg] - lappend v $msg -} {0 {}} -do_test pager2-2.20 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 1 state 1 err 0 hit 1 miss 1 ovfl 0} -do_test pager2-2.19 { - pager_pagecount $::p1 -} {1} -do_test pager2-2.21 { - pager_stats $::p1 -} {ref 1 page 1 max 10 size 1 state 1 err 0 hit 1 miss 1 ovfl 0} -do_test pager2-2.22 { - page_unref $::g1 -} {} -do_test pager2-2.23 { - pager_stats $::p1 -} {ref 0 page 1 max 10 size 1 state 1 err 0 hit 1 miss 1 ovfl 0} -do_test pager2-2.24 { - set v [catch { - page_get $::p1 1 - } ::g1] - if {$v} {lappend v $::g1} - set v -} {0} -do_test pager2-2.25 { - page_read $::g1 -} {Page-One} -do_test pager2-2.26 { - set v [catch { - page_write $::g1 {page-one} - } msg] - lappend v $msg -} {0 {}} -do_test pager2-2.27 { - page_read $::g1 -} {page-one} -do_test pager2-2.28 { - set v [catch { - pager_rollback $::p1 - } msg] - lappend v $msg -} {0 {}} -do_test pager2-2.29 { - page_unref $::g1 - set ::g1 [page_get $::p1 1] - page_read $::g1 -} {Page-One} -#do_test pager2-2.99 { -# pager_close $::p1 -#} {} - -#do_test pager2-3.1 { -# set v [catch { -# set ::p1 [pager_open :memory: 15] -# } msg] -# if {$v} {lappend v $msg} -# set v -#} {0} -do_test pager2-3.2 { - pager_pagecount $::p1 -} {1} -do_test pager2-3.3 { - set v [catch { - set ::g(1) [page_get $::p1 1] - } msg] - if {$v} {lappend v $msg} - set v -} {0} -do_test pager2-3.4 { - page_read $::g(1) -} {Page-One} -do_test pager2-3.5 { - for {set i 2} {$i<=20} {incr i} { - set gx [page_get $::p1 $i] - page_write $gx "Page-$i" - page_unref $gx - } - pager_commit $::p1 -} {} -for {set i 2} {$i<=20} {incr i} { - do_test pager2-3.6.[expr {$i-1}] [subst { - set gx \[page_get $::p1 $i\] - set v \[page_read \$gx\] - page_unref \$gx - set v - }] "Page-$i" -} -for {set i 1} {$i<=20} {incr i} { - regsub -all CNT { - set ::g1 [page_get $::p1 CNT] - set ::g2 [page_get $::p1 CNT] - set ::vx [page_read $::g2] - expr {$::g1==$::g2} - } $i body; - do_test pager2-3.7.$i.1 $body {1} - regsub -all CNT { - page_unref $::g2 - set vy [page_read $::g1] - expr {$vy==$::vx} - } $i body; - do_test pager2-3.7.$i.2 $body {1} - regsub -all CNT { - page_unref $::g1 - set gx [page_get $::p1 CNT] - set vy [page_read $gx] - page_unref $gx - expr {$vy==$::vx} - } $i body; - do_test pager2-3.7.$i.3 $body {1} -} -do_test pager2-3.99 { - pager_close $::p1 -} {} - -# tests of the checkpoint mechanism and api -# -do_test pager2-4.0 { - set v [catch { - set ::p1 [pager_open :memory: 15] - } msg] - if {$v} {lappend v $msg} - set v -} {0} -do_test pager2-4.1 { - set g1 [page_get $::p1 1] - page_write $g1 "Page-1 v0" - for {set i 2} {$i<=20} {incr i} { - set gx [page_get $::p1 $i] - page_write $gx "Page-$i v0" - page_unref $gx - } - pager_commit $::p1 -} {} -for {set i 1} {$i<=20} {incr i} { - do_test pager2-4.2.$i { - set gx [page_get $p1 $i] - set v [page_read $gx] - page_unref $gx - set v - } "Page-$i v0" -} -do_test pager2-4.3 { - lrange [pager_stats $::p1] 0 1 -} {ref 1} -do_test pager2-4.4 { - lrange [pager_stats $::p1] 8 9 -} {state 1} - -for {set i 1} {$i<20} {incr i} { - do_test pager2-4.5.$i.0 { - set res {} - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - set value [page_read $gx] - page_unref $gx - set shouldbe "Page-$j v[expr {$i-1}]" - if {$value!=$shouldbe} { - lappend res $value $shouldbe - } - } - set res - } {} - do_test pager2-4.5.$i.1 { - page_write $g1 "Page-1 v$i" - lrange [pager_stats $p1] 8 9 - } {state 4} - do_test pager2-4.5.$i.2 { - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - page_write $gx "Page-$j v$i" - page_unref $gx - if {$j==$i} { - pager_stmt_begin $p1 - } - } - } {} - do_test pager2-4.5.$i.3 { - set res {} - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - set value [page_read $gx] - page_unref $gx - set shouldbe "Page-$j v$i" - if {$value!=$shouldbe} { - lappend res $value $shouldbe - } - } - set res - } {} - do_test pager2-4.5.$i.4 { - pager_rollback $p1 - set res {} - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - set value [page_read $gx] - page_unref $gx - set shouldbe "Page-$j v[expr {$i-1}]" - if {$value!=$shouldbe} { - lappend res $value $shouldbe - } - } - set res - } {} - do_test pager2-4.5.$i.5 { - page_write $g1 "Page-1 v$i" - lrange [pager_stats $p1] 8 9 - } {state 4} - do_test pager2-4.5.$i.6 { - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - page_write $gx "Page-$j v$i" - page_unref $gx - if {$j==$i} { - pager_stmt_begin $p1 - } - } - } {} - do_test pager2-4.5.$i.7 { - pager_stmt_rollback $p1 - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - set value [page_read $gx] - page_unref $gx - if {$j<=$i || $i==1} { - set shouldbe "Page-$j v$i" - } else { - set shouldbe "Page-$j v[expr {$i-1}]" - } - if {$value!=$shouldbe} { - lappend res $value $shouldbe - } - } - set res - } {} - do_test pager2-4.5.$i.8 { - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - page_write $gx "Page-$j v$i" - page_unref $gx - if {$j==$i} { - pager_stmt_begin $p1 - } - } - } {} - do_test pager2-4.5.$i.9 { - pager_stmt_commit $p1 - for {set j 2} {$j<=20} {incr j} { - set gx [page_get $p1 $j] - set value [page_read $gx] - page_unref $gx - set shouldbe "Page-$j v$i" - if {$value!=$shouldbe} { - lappend res $value $shouldbe - } - } - set res - } {} - do_test pager2-4.5.$i.10 { - pager_commit $p1 - lrange [pager_stats $p1] 8 9 - } {state 1} -} - -do_test pager2-4.99 { - pager_close $::p1 -} {} - -} ;# ifcapable inmemory -} ;# end if( has pager_open command ); - - -finish_test diff --git a/sqlite/test/pager3.test b/sqlite/test/pager3.test deleted file mode 100644 index 9c3b6e1..0000000 --- a/sqlite/test/pager3.test +++ /dev/null @@ -1,71 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this script is page cache subsystem. -# -# $Id: pager3.test,v 1.2 2004/11/04 14:47:13 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# This test makes sure the database file is truncated back to the correct -# length on a rollback. -# -# After some preliminary setup, a transaction is start at NOTE (1). -# The create table on the following line allocates an additional page -# at the end of the database file. But that page is not written because -# the database still has a RESERVED lock, not an EXCLUSIVE lock. The -# new page is held in memory and the size of the file is unchanged. -# The insert at NOTE (2) begins adding additional pages. Then it hits -# a constraint error and aborts. The abort causes sqlite3OsTruncate() -# to be called to restore the file to the same length as it was after -# the create table. But the create table results had not yet been -# written so the file is actually lengthened by this truncate. Finally, -# the rollback at NOTE (3) is called to undo all the changes since the -# begin. This rollback should truncate the database again. -# -# This test was added because the second truncate at NOTE (3) was not -# occurring on early versions of SQLite 3.0. -# -do_test pager3-1.1 { - execsql { - create table t1(a unique, b); - insert into t1 values(1, 'abcdefghijklmnopqrstuvwxyz'); - insert into t1 values(2, 'abcdefghijklmnopqrstuvwxyz'); - update t1 set b=b||a||b; - update t1 set b=b||a||b; - update t1 set b=b||a||b; - update t1 set b=b||a||b; - update t1 set b=b||a||b; - update t1 set b=b||a||b; - create temp table t2 as select * from t1; - begin; ------- NOTE (1) - create table t3(x); - } - catchsql { - insert into t1 select 4-a, b from t2; ----- NOTE (2) - } - execsql { - rollback; ------- NOTE (3) - } - db close - sqlite3 db test.db - set r ok - ifcapable {integrityck} { - set r [execsql { - pragma integrity_check; - }] - } - set r -} ok - -finish_test diff --git a/sqlite/test/pagesize.test b/sqlite/test/pagesize.test deleted file mode 100644 index 072b07e..0000000 --- a/sqlite/test/pagesize.test +++ /dev/null @@ -1,171 +0,0 @@ -# 2004 September 2 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# This file implements tests for the page_size PRAGMA. -# -# $Id: pagesize.test,v 1.9 2004/11/23 10:52:51 danielk1977 Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# This test script depends entirely on "PRAGMA page_size". So if this -# pragma is not available, omit the whole file. -ifcapable !pager_pragmas { - finish_test - return -} - -do_test pagesize-1.1 { - execsql {PRAGMA page_size} -} 1024 -ifcapable {explain} { - do_test pagesize-1.2 { - catch {execsql {EXPLAIN PRAGMA page_size}} - } 0 -} -do_test pagesize-1.3 { - execsql { - CREATE TABLE t1(a); - PRAGMA page_size=2048; - PRAGMA page_size; - } -} 1024 - -do_test pagesize-1.4 { - db close - file delete -force test.db - sqlite3 db test.db - execsql { - PRAGMA page_size=511; - PRAGMA page_size; - } -} 1024 -do_test pagesize-1.5 { - execsql { - PRAGMA page_size=512; - PRAGMA page_size; - } -} 512 -do_test pagesize-1.6 { - execsql { - PRAGMA page_size=8192; - PRAGMA page_size; - } -} 8192 -do_test pagesize-1.7 { - execsql { - PRAGMA page_size=65537; - PRAGMA page_size; - } -} 8192 -do_test pagesize-1.8 { - execsql { - PRAGMA page_size=1234; - PRAGMA page_size - } -} 8192 - -foreach PGSZ {512 2048 4096 8192} { - do_test pagesize-2.$PGSZ.1 { - db close - file delete -force test.db - sqlite3 db test.db - execsql "PRAGMA page_size=$PGSZ" - execsql { - CREATE TABLE t1(x); - PRAGMA page_size; - } - } $PGSZ - do_test pagesize-2.$PGSZ.2 { - db close - sqlite3 db test.db - execsql { - PRAGMA page_size - } - } $PGSZ - do_test pagesize-2.$PGSZ.3 { - file size test.db - } [expr {$PGSZ*($AUTOVACUUM?3:2)}] - ifcapable {vacuum} { - do_test pagesize-2.$PGSZ.4 { - execsql {VACUUM} - } {} - } - integrity_check pagesize-2.$PGSZ.5 - do_test pagesize-2.$PGSZ.6 { - db close - sqlite3 db test.db - execsql {PRAGMA page_size} - } $PGSZ - do_test pagesize-2.$PGSZ.7 { - execsql { - INSERT INTO t1 VALUES(randstr(10,9000)); - INSERT INTO t1 VALUES(randstr(10,9000)); - INSERT INTO t1 VALUES(randstr(10,9000)); - BEGIN; - INSERT INTO t1 SELECT x||x FROM t1; - INSERT INTO t1 SELECT x||x FROM t1; - INSERT INTO t1 SELECT x||x FROM t1; - INSERT INTO t1 SELECT x||x FROM t1; - SELECT count(*) FROM t1; - } - } 48 - do_test pagesize-2.$PGSZ.8 { - execsql { - ROLLBACK; - SELECT count(*) FROM t1; - } - } 3 - integrity_check pagesize-2.$PGSZ.9 - do_test pagesize-2.$PGSZ.10 { - db close - sqlite3 db test.db - execsql {PRAGMA page_size} - } $PGSZ - do_test pagesize-2.$PGSZ.11 { - execsql { - INSERT INTO t1 SELECT x||x FROM t1; - INSERT INTO t1 SELECT x||x FROM t1; - INSERT INTO t1 SELECT x||x FROM t1; - INSERT INTO t1 SELECT x||x FROM t1; - INSERT INTO t1 SELECT x||x FROM t1; - INSERT INTO t1 SELECT x||x FROM t1; - SELECT count(*) FROM t1; - } - } 192 - do_test pagesize-2.$PGSZ.12 { - execsql { - BEGIN; - DELETE FROM t1 WHERE rowid%5!=0; - SELECT count(*) FROM t1; - } - } 38 - do_test pagesize-2.$PGSZ.13 { - execsql { - ROLLBACK; - SELECT count(*) FROM t1; - } - } 192 - integrity_check pagesize-2.$PGSZ.14 - do_test pagesize-2.$PGSZ.15 { - execsql {DELETE FROM t1 WHERE rowid%5!=0} - ifcapable {vacuum} {execsql VACUUM} - execsql {SELECT count(*) FROM t1} - } 38 - do_test pagesize-2.$PGSZ.16 { - execsql {DROP TABLE t1} - ifcapable {vacuum} {execsql VACUUM} - } {} - integrity_check pagesize-2.$PGSZ.17 -} - -finish_test diff --git a/sqlite/test/pragma.test b/sqlite/test/pragma.test deleted file mode 100644 index abb8ef1..0000000 --- a/sqlite/test/pragma.test +++ /dev/null @@ -1,763 +0,0 @@ -# 2002 March 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 implements regression tests for SQLite library. -# -# This file implements tests for the PRAGMA command. -# -# $Id: pragma.test,v 1.34 2005/02/13 23:34:25 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Test organization: -# -# pragma-1.*: Test cache_size, default_cache_size and synchronous on main db. -# pragma-2.*: Test synchronous on attached db. -# pragma-3.*: Test detection of table/index inconsistency by integrity_check. -# pragma-4.*: Test cache_size and default_cache_size on attached db. -# pragma-5.*: Test that pragma synchronous may not be used inside of a -# transaction. -# pragma-6.*: Test schema-query pragmas. -# pragma-7.*: Miscellaneous tests. -# pragma-8.*: Test user_version and schema_version pragmas. -# pragma-9.*: Test temp_store and temp_store_directory. -# pragma-10.*: Test the count_changes pragma in the presence of triggers. -# pragma-11.*: Test the collation_list pragma. -# - -# Delete the preexisting database to avoid the special setup -# that the "all.test" script does. -# -db close -file delete test.db -set DB [sqlite3 db test.db] - -ifcapable pager_pragmas { -do_test pragma-1.1 { - execsql { - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {2000 2000 2} -do_test pragma-1.2 { - execsql { - PRAGMA cache_size=1234; - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {1234 2000 2} -do_test pragma-1.3 { - db close - sqlite3 db test.db - execsql { - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {2000 2000 2} -do_test pragma-1.4 { - execsql { - PRAGMA synchronous=OFF; - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {2000 2000 0} -do_test pragma-1.5 { - execsql { - PRAGMA cache_size=4321; - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {4321 2000 0} -do_test pragma-1.6 { - execsql { - PRAGMA synchronous=ON; - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {4321 2000 1} -do_test pragma-1.7 { - db close - sqlite3 db test.db - execsql { - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {2000 2000 2} -do_test pragma-1.8 { - execsql { - PRAGMA default_cache_size=123; - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {123 123 2} -do_test pragma-1.9.1 { - db close - set ::DB [sqlite3 db test.db] - execsql { - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {123 123 2} -ifcapable vacuum { - do_test pragma-1.9.2 { - execsql { - VACUUM; - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } - } {123 123 2} -} -do_test pragma-1.10 { - execsql { - PRAGMA synchronous=NORMAL; - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {123 123 1} -do_test pragma-1.11 { - execsql { - PRAGMA synchronous=FULL; - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {123 123 2} -do_test pragma-1.12 { - db close - set ::DB [sqlite3 db test.db] - execsql { - PRAGMA cache_size; - PRAGMA default_cache_size; - PRAGMA synchronous; - } -} {123 123 2} - -# Make sure the pragma handler understands numeric values in addition -# to keywords like "off" and "full". -# -do_test pragma-1.13 { - execsql { - PRAGMA synchronous=0; - PRAGMA synchronous; - } -} {0} -do_test pragma-1.14 { - execsql { - PRAGMA synchronous=2; - PRAGMA synchronous; - } -} {2} -} ;# ifcapable pager_pragmas - -# Test turning "flag" pragmas on and off. -# -do_test pragma-1.15 { - execsql { - PRAGMA vdbe_listing=YES; - PRAGMA vdbe_listing; - } -} {1} -do_test pragma-1.16 { - execsql { - PRAGMA vdbe_listing=NO; - PRAGMA vdbe_listing; - } -} {0} -do_test pragma-1.17 { - execsql { - PRAGMA parser_trace=ON; - PRAGMA parser_trace=OFF; - } -} {} -do_test pragma-1.18 { - execsql { - PRAGMA bogus = -1234; -- Parsing of negative values - } -} {} - -# Test modifying the safety_level of an attached database. -do_test pragma-2.1 { - file delete -force test2.db - file delete -force test2.db-journal - execsql { - ATTACH 'test2.db' AS aux; - } -} {} -ifcapable pager_pragmas { -do_test pragma-2.2 { - execsql { - pragma aux.synchronous; - } -} {2} -do_test pragma-2.3 { - execsql { - pragma aux.synchronous = OFF; - pragma aux.synchronous; - pragma synchronous; - } -} {0 2} -do_test pragma-2.4 { - execsql { - pragma aux.synchronous = ON; - pragma synchronous; - pragma aux.synchronous; - } -} {2 1} -} ;# ifcapable pager_pragmas - -# Construct a corrupted index and make sure the integrity_check -# pragma finds it. -# -# These tests won't work if the database is encrypted -# -do_test pragma-3.1 { - execsql { - BEGIN; - CREATE TABLE t2(a,b,c); - CREATE INDEX i2 ON t2(a); - INSERT INTO t2 VALUES(11,2,3); - INSERT INTO t2 VALUES(22,3,4); - COMMIT; - SELECT rowid, * from t2; - } -} {1 11 2 3 2 22 3 4} -if {![sqlite3 -has-codec] && $sqlite_options(integrityck)} { - do_test pragma-3.2 { - set rootpage [execsql {SELECT rootpage FROM sqlite_master WHERE name='i2'}] - set db [btree_open test.db 100 0] - btree_begin_transaction $db - set c [btree_cursor $db $rootpage 1] - btree_first $c - btree_delete $c - btree_commit $db - btree_close $db - execsql {PRAGMA integrity_check} - } {{rowid 1 missing from index i2} {wrong # of entries in index i2}} -} -do_test pragma-3.3 { - execsql { - DROP INDEX i2; - } -} {} - -# Test modifying the cache_size of an attached database. -ifcapable pager_pragmas { -do_test pragma-4.1 { - execsql { - pragma aux.cache_size; - pragma aux.default_cache_size; - } -} {2000 2000} -do_test pragma-4.2 { - execsql { - pragma aux.cache_size = 50; - pragma aux.cache_size; - pragma aux.default_cache_size; - } -} {50 2000} -do_test pragma-4.3 { - execsql { - pragma aux.default_cache_size = 456; - pragma aux.cache_size; - pragma aux.default_cache_size; - } -} {456 456} -do_test pragma-4.4 { - execsql { - pragma cache_size; - pragma default_cache_size; - } -} {123 123} -do_test pragma-4.5 { - execsql { - DETACH aux; - ATTACH 'test3.db' AS aux; - pragma aux.cache_size; - pragma aux.default_cache_size; - } -} {2000 2000} -do_test pragma-4.6 { - execsql { - DETACH aux; - ATTACH 'test2.db' AS aux; - pragma aux.cache_size; - pragma aux.default_cache_size; - } -} {456 456} -} ;# ifcapable pager_pragmas - -# Test that modifying the sync-level in the middle of a transaction is -# disallowed. -ifcapable pager_pragmas { -do_test pragma-5.0 { - execsql { - pragma synchronous; - } -} {2} -do_test pragma-5.1 { - catchsql { - BEGIN; - pragma synchronous = OFF; - } -} {1 {Safety level may not be changed inside a transaction}} -do_test pragma-5.2 { - execsql { - pragma synchronous; - } -} {2} -catchsql {COMMIT;} -} ;# ifcapable pager_pragmas - -# Test schema-query pragmas -# -ifcapable schema_pragmas { -do_test pragma-6.1 { - set res {} - execsql {SELECT * FROM sqlite_temp_master} - foreach {idx name file} [execsql {pragma database_list}] { - lappend res $idx $name - } - set res -} {0 main 1 temp 2 aux} -do_test pragma-6.2 { - execsql { - pragma table_info(t2) - } -} {0 a numeric 0 {} 0 1 b numeric 0 {} 0 2 c numeric 0 {} 0} -ifcapable {foreignkey} { - do_test pragma-6.3 { - execsql { - CREATE TABLE t3(a int references t2(b), b UNIQUE); - pragma foreign_key_list(t3); - } - } {0 0 t2 a b} - do_test pragma-6.4 { - execsql { - pragma index_list(t3); - } - } {0 sqlite_autoindex_t3_1 1} -} -ifcapable {!foreignkey} { - execsql {CREATE TABLE t3(a,b UNIQUE)} -} -do_test pragma-6.5 { - execsql { - CREATE INDEX t3i1 ON t3(a,b); - pragma index_info(t3i1); - } -} {0 0 a 1 1 b} -} ;# ifcapable schema_pragmas -# Miscellaneous tests -# -ifcapable schema_pragmas { -do_test pragma-7.1 { - # Make sure a pragma knows to read the schema if it needs to - db close - sqlite3 db test.db - execsql { - pragma index_list(t3); - } -} {0 t3i1 0 1 sqlite_autoindex_t3_1 1} -} ;# ifcapable schema_pragmas -ifcapable {utf16} { - do_test pragma-7.2 { - db close - sqlite3 db test.db - catchsql { - pragma encoding=bogus; - } - } {1 {unsupported encoding: bogus}} -} -do_test pragma-7.3 { - db close - sqlite3 db test.db - execsql { - pragma lock_status; - } -} {main unlocked temp closed} - - -#---------------------------------------------------------------------- -# Test cases pragma-8.* test the "PRAGMA schema_version" and "PRAGMA -# user_version" statements. -# -# pragma-8.1: PRAGMA schema_version -# pragma-8.2: PRAGMA user_version -# - -ifcapable schema_version { - -# First check that we can set the schema version and then retrieve the -# same value. -do_test pragma-8.1.1 { - execsql { - PRAGMA schema_version = 105; - } -} {} -do_test pragma-8.1.2 { - execsql { - PRAGMA schema_version; - } -} 105 -do_test pragma-8.1.3 { - execsql { - PRAGMA schema_version = 106; - } -} {} -do_test pragma-8.1.4 { - execsql { - PRAGMA schema_version; - } -} 106 - -# Check that creating a table modifies the schema-version (this is really -# to verify that the value being read is in fact the schema version). -do_test pragma-8.1.5 { - execsql { - CREATE TABLE t4(a, b, c); - INSERT INTO t4 VALUES(1, 2, 3); - SELECT * FROM t4; - } -} {1 2 3} -do_test pragma-8.1.6 { - execsql { - PRAGMA schema_version; - } -} 107 - -# Now open a second connection to the database. Ensure that changing the -# schema-version using the first connection forces the second connection -# to reload the schema. This has to be done using the C-API test functions, -# because the TCL API accounts for SCHEMA_ERROR and retries the query. -do_test pragma-8.1.7 { - set ::DB2 [sqlite3 db2 test.db] - execsql { - SELECT * FROM t4; - } db2 -} {1 2 3} -do_test pragma-8.1.8 { - execsql { - PRAGMA schema_version = 108; - } -} {} -do_test pragma-8.1.9 { - set ::STMT [sqlite3_prepare $::DB2 "SELECT * FROM t4" -1 DUMMY] - sqlite3_step $::STMT -} SQLITE_ERROR -do_test pragma-8.1.10 { - sqlite3_finalize $::STMT -} SQLITE_SCHEMA - -# Make sure the schema-version can be manipulated in an attached database. -file delete -force test2.db -file delete -force test2.db-journal -do_test pragma-8.1.11 { - execsql { - ATTACH 'test2.db' AS aux; - CREATE TABLE aux.t1(a, b, c); - PRAGMA aux.schema_version = 205; - } -} {} -do_test pragma-8.1.12 { - execsql { - PRAGMA aux.schema_version; - } -} 205 -do_test pragma-8.1.13 { - execsql { - PRAGMA schema_version; - } -} 108 - -# And check that modifying the schema-version in an attached database -# forces the second connection to reload the schema. -do_test pragma-8.1.14 { - set ::DB2 [sqlite3 db2 test.db] - execsql { - ATTACH 'test2.db' AS aux; - SELECT * FROM aux.t1; - } db2 -} {} -do_test pragma-8.1.15 { - execsql { - PRAGMA aux.schema_version = 206; - } -} {} -do_test pragma-8.1.16 { - set ::STMT [sqlite3_prepare $::DB2 "SELECT * FROM aux.t1" -1 DUMMY] - sqlite3_step $::STMT -} SQLITE_ERROR -do_test pragma-8.1.17 { - sqlite3_finalize $::STMT -} SQLITE_SCHEMA -do_test pragma-8.1.18 { - db2 close -} {} - -# Now test that the user-version can be read and written (and that we aren't -# accidentally manipulating the schema-version instead). -do_test pragma-8.2.1 { - execsql { - PRAGMA user_version; - } -} {0} -do_test pragma-8.2.2 { - execsql { - PRAGMA user_version = 2; - } -} {} -do_test pragma-8.2.3.1 { - execsql { - PRAGMA user_version; - } -} {2} -do_test pragma-8.2.3.2 { - db close - sqlite3 db test.db - execsql { - PRAGMA user_version; - } -} {2} -do_test pragma-8.2.4.1 { - execsql { - PRAGMA schema_version; - } -} {108} -ifcapable vacuum { - do_test pragma-8.2.4.2 { - execsql { - VACUUM; - PRAGMA user_version; - } - } {2} - do_test pragma-8.2.4.3 { - execsql { - PRAGMA schema_version; - } - } {109} -} -db eval {ATTACH 'test2.db' AS aux} - -# Check that the user-version in the auxilary database can be manipulated ( -# and that we aren't accidentally manipulating the same in the main db). -do_test pragma-8.2.5 { - execsql { - PRAGMA aux.user_version; - } -} {0} -do_test pragma-8.2.6 { - execsql { - PRAGMA aux.user_version = 3; - } -} {} -do_test pragma-8.2.7 { - execsql { - PRAGMA aux.user_version; - } -} {3} -do_test pragma-8.2.8 { - execsql { - PRAGMA main.user_version; - } -} {2} - -# Now check that a ROLLBACK resets the user-version if it has been modified -# within a transaction. -do_test pragma-8.2.9 { - execsql { - BEGIN; - PRAGMA aux.user_version = 10; - PRAGMA user_version = 11; - } -} {} -do_test pragma-8.2.10 { - execsql { - PRAGMA aux.user_version; - } -} {10} -do_test pragma-8.2.11 { - execsql { - PRAGMA main.user_version; - } -} {11} -do_test pragma-8.2.12 { - execsql { - ROLLBACK; - PRAGMA aux.user_version; - } -} {3} -do_test pragma-8.2.13 { - execsql { - PRAGMA main.user_version; - } -} {2} - -# Try a negative value for the user-version -do_test pragma-8.2.14 { - execsql { - PRAGMA user_version = -450; - } -} {} -do_test pragma-8.2.15 { - execsql { - PRAGMA user_version; - } -} {-450} -} ; # ifcapable schema_version - - -# Test temp_store and temp_store_directory pragmas -# -ifcapable pager_pragmas { -do_test pragma-9.1 { - db close - sqlite3 db test.db - execsql { - PRAGMA temp_store; - } -} {0} -do_test pragma-9.2 { - execsql { - PRAGMA temp_store=file; - PRAGMA temp_store; - } -} {1} -do_test pragma-9.3 { - execsql { - PRAGMA temp_store=memory; - PRAGMA temp_store; - } -} {2} -do_test pragma-9.4 { - execsql { - PRAGMA temp_store_directory; - } -} {} -do_test pragma-9.5 { - set pwd [string map {' ''} [pwd]] - execsql " - PRAGMA temp_store_directory='$pwd'; - " -} {} -do_test pragma-9.6 { - execsql { - PRAGMA temp_store_directory; - } -} [pwd] -do_test pragma-9.7 { - catchsql { - PRAGMA temp_store_directory='/NON/EXISTENT/PATH/FOOBAR'; - } -} {1 {not a writable directory}} -do_test pragma-9.8 { - execsql { - PRAGMA temp_store_directory=''; - } -} {} -do_test pragma-9.9 { - execsql { - PRAGMA temp_store_directory; - PRAGMA temp_store=FILE; - CREATE TEMP TABLE temp_store_directory_test(a integer); - INSERT INTO temp_store_directory_test values (2); - SELECT * FROM temp_store_directory_test; - } -} {2} -do_test pragma-9.10 { - catchsql " - PRAGMA temp_store_directory='$pwd'; - SELECT * FROM temp_store_directory_test; - " -} {1 {no such table: temp_store_directory_test}} -} ;# ifcapable pager_pragmas - -ifcapable trigger { - -do_test pragma-10.0 { - catchsql { - DROP TABLE main.t1; - } - execsql { - PRAGMA count_changes = 1; - - CREATE TABLE t1(a PRIMARY KEY); - CREATE TABLE t1_mirror(a); - CREATE TABLE t1_mirror2(a); - CREATE TRIGGER t1_bi BEFORE INSERT ON t1 BEGIN - INSERT INTO t1_mirror VALUES(new.a); - END; - CREATE TRIGGER t1_ai AFTER INSERT ON t1 BEGIN - INSERT INTO t1_mirror2 VALUES(new.a); - END; - CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 BEGIN - UPDATE t1_mirror SET a = new.a WHERE a = old.a; - END; - CREATE TRIGGER t1_au AFTER UPDATE ON t1 BEGIN - UPDATE t1_mirror2 SET a = new.a WHERE a = old.a; - END; - CREATE TRIGGER t1_bd BEFORE DELETE ON t1 BEGIN - DELETE FROM t1_mirror WHERE a = old.a; - END; - CREATE TRIGGER t1_ad AFTER DELETE ON t1 BEGIN - DELETE FROM t1_mirror2 WHERE a = old.a; - END; - } -} {} - -do_test pragma-10.1 { - execsql { - INSERT INTO t1 VALUES(randstr(10,10)); - } -} {1} -do_test pragma-10.2 { - execsql { - UPDATE t1 SET a = randstr(10,10); - } -} {1} -do_test pragma-10.3 { - execsql { - DELETE FROM t1; - } -} {1} - -} ;# ifcapable trigger - -ifcapable schema_pragmas { - do_test pragma-11.1 { - execsql2 { - pragma collation_list; - } - } {seq 0 name NOCASE seq 1 name BINARY} - do_test pragma-11.2 { - db collate New_Collation blah... - execsql { - pragma collation_list; - } - } {0 New_Collation 1 NOCASE 2 BINARY} -} - -# Reset the sqlite3_temp_directory variable for the next run of tests: -sqlite3 dbX :memory: -dbX eval {PRAGMA temp_store_directory = ""} -dbX close - -finish_test diff --git a/sqlite/test/progress.test b/sqlite/test/progress.test deleted file mode 100755 index 5a0d186..0000000 --- a/sqlite/test/progress.test +++ /dev/null @@ -1,132 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the 'progress callback'. -# -# $Id: progress.test,v 1.5 2005/01/20 02:17:02 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If the progress callback is not available in this build, skip this -# whole file. -ifcapable !progress { - finish_test - return -} - -# Build some test data -# -execsql { - BEGIN; - CREATE TABLE t1(a); - INSERT INTO t1 VALUES(1); - INSERT INTO t1 VALUES(2); - INSERT INTO t1 VALUES(3); - INSERT INTO t1 VALUES(4); - INSERT INTO t1 VALUES(5); - INSERT INTO t1 VALUES(6); - INSERT INTO t1 VALUES(7); - INSERT INTO t1 VALUES(8); - INSERT INTO t1 VALUES(9); - INSERT INTO t1 VALUES(10); - COMMIT; -} - - -# Test that the progress callback is invoked. -do_test progress-1.0 { - set counter 0 - db progress 1 "[namespace code {incr counter}] ; expr 0" - execsql { - SELECT * FROM t1 - } - expr $counter > 1 -} 1 -do_test progress-1.0.1 { - db progress -} {::namespace inscope :: {incr counter} ; expr 0} -do_test progress-1.0.2 { - set v [catch {db progress xyz bogus} msg] - lappend v $msg -} {1 {expected integer but got "xyz"}} - -# Test that the query is abandoned when the progress callback returns non-zero -do_test progress-1.1 { - set counter 0 - db progress 1 "[namespace code {incr counter}] ; expr 1" - set rc [catch {execsql { - SELECT * FROM t1 - }}] - list $counter $rc -} {1 1} - -# Test that the query is rolled back when the progress callback returns -# non-zero. -do_test progress-1.2 { - - # This figures out how many opcodes it takes to copy 5 extra rows into t1. - db progress 1 "[namespace code {incr five_rows}] ; expr 0" - set five_rows 0 - execsql { - INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 6 - } - db progress 0 "" - execsql { - DELETE FROM t1 WHERE a > 10 - } - - # Now set up the progress callback to abandon the query after the number of - # opcodes to copy 5 rows. That way, when we try to copy 6 rows, we know - # some data will have been inserted into the table by the time the progress - # callback abandons the query. - db progress $five_rows "expr 1" - catchsql { - INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 9 - } - execsql { - SELECT count(*) FROM t1 - } -} 10 - -# Test that an active transaction remains active and not rolled back after the -# progress query abandons a query. -do_test progress-1.3 { - - db progress 0 "" - execsql BEGIN - execsql { - INSERT INTO t1 VALUES(11) - } - db progress 1 "expr 1" - catchsql { - INSERT INTO t1 VALUES(12) - } - db progress 0 "" - execsql COMMIT - execsql { - SELECT count(*) FROM t1 - } -} 11 - -# Check that a value of 0 for N means no progress callback -do_test progress-1.4 { - set counter 0 - db progress 0 "[namespace code {incr counter}] ; expr 0" - execsql { - SELECT * FROM t1; - } - set counter -} 0 - -db progress 0 "" - -finish_test diff --git a/sqlite/test/quick.test b/sqlite/test/quick.test deleted file mode 100644 index 8cc30cf..0000000 --- a/sqlite/test/quick.test +++ /dev/null @@ -1,58 +0,0 @@ -# 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 runs all tests. -# -# $Id: quick.test,v 1.33 2004/11/13 13:19:56 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -rename finish_test really_finish_test -proc finish_test {} {} -set ISQUICK 1 - -set EXCLUDE { - all.test - btree2.test - btree3.test - btree4.test - btree5.test - btree6.test - corrupt.test - crash.test - malloc.test - memleak.test - misuse.test - quick.test - utf16.test - autovacuum_crash.test - btree8.test -} - -if {[sqlite3 -has-codec]} { - # lappend EXCLUDE \ - # conflict.test -} - -foreach testfile [lsort -dictionary [glob $testdir/*.test]] { - set tail [file tail $testfile] - if {[lsearch -exact $EXCLUDE $tail]>=0} continue - source $testfile - catch {db close} - if {$sqlite_open_file_count>0} { - puts "$tail did not close all files: $sqlite_open_file_count" - incr nErr - lappend ::failList $tail - } -} -source $testdir/misuse.test - -set sqlite_open_file_count 0 -really_finish_test diff --git a/sqlite/test/reindex.test b/sqlite/test/reindex.test deleted file mode 100644 index 503d797..0000000 --- a/sqlite/test/reindex.test +++ /dev/null @@ -1,172 +0,0 @@ -# 2004 November 5 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# This file implements tests for the REINDEX command. -# -# $Id: reindex.test,v 1.3 2005/01/27 00:22:04 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# There is nothing to test if REINDEX is disable for this build. -# -ifcapable {!reindex} { - finish_test - return -} - -# Basic sanity checks. -# -do_test reindex-1.1 { - execsql { - CREATE TABLE t1(a,b); - INSERT INTO t1 VALUES(1,2); - INSERT INTO t1 VALUES(3,4); - CREATE INDEX i1 ON t1(a); - REINDEX; - } -} {} -integrity_check reindex-1.2 -do_test reindex-1.3 { - execsql { - REINDEX t1; - } -} {} -integrity_check reindex-1.4 -do_test reindex-1.5 { - execsql { - REINDEX i1; - } -} {} -integrity_check reindex-1.6 -do_test reindex-1.7 { - execsql { - REINDEX main.t1; - } -} {} -do_test reindex-1.8 { - execsql { - REINDEX main.i1; - } -} {} -do_test reindex-1.9 { - catchsql { - REINDEX bogus - } -} {1 {unable to identify the object to be reindexed}} - -# Set up a table for testing that includes several different collating -# sequences including some that we can modify. -# -do_test reindex-2.1 { - proc c1 {a b} { - return [expr {-[string compare $a $b]}] - } - proc c2 {a b} { - return [expr {-[string compare [string tolower $a] [string tolower $b]]}] - } - db collate c1 c1 - db collate c2 c2 - execsql { - CREATE TABLE t2( - a TEXT PRIMARY KEY COLLATE c1, - b TEXT UNIQUE COLLATE c2, - c TEXT COLLATE nocase, - d TEST COLLATE binary - ); - INSERT INTO t2 VALUES('abc','abc','abc','abc'); - INSERT INTO t2 VALUES('ABCD','ABCD','ABCD','ABCD'); - INSERT INTO t2 VALUES('bcd','bcd','bcd','bcd'); - INSERT INTO t2 VALUES('BCDE','BCDE','BCDE','BCDE'); - SELECT a FROM t2 ORDER BY a; - } -} {bcd abc BCDE ABCD} -do_test reindex-2.2 { - execsql { - SELECT b FROM t2 ORDER BY b; - } -} {BCDE bcd ABCD abc} -do_test reindex-2.3 { - execsql { - SELECT c FROM t2 ORDER BY c; - } -} {abc ABCD bcd BCDE} -do_test reindex-2.4 { - execsql { - SELECT d FROM t2 ORDER BY d; - } -} {ABCD BCDE abc bcd} - -# Change a collating sequence function. Verify that REINDEX rebuilds -# the index. -# -do_test reindex-2.5 { - proc c1 {a b} { - return [string compare $a $b] - } - execsql { - SELECT a FROM t2 ORDER BY a; - } -} {bcd abc BCDE ABCD} -ifcapable {integrityck} { - do_test reindex-2.5.1 { - string equal ok [execsql {PRAGMA integrity_check}] - } {0} -} -do_test reindex-2.6 { - execsql { - REINDEX c2; - SELECT a FROM t2 ORDER BY a; - } -} {bcd abc BCDE ABCD} -do_test reindex-2.7 { - execsql { - REINDEX t1; - SELECT a FROM t2 ORDER BY a; - } -} {bcd abc BCDE ABCD} -do_test reindex-2.8 { - execsql { - REINDEX c1; - SELECT a FROM t2 ORDER BY a; - } -} {ABCD BCDE abc bcd} -integrity_check reindex-2.8.1 - -# Try to REINDEX an index for which the collation sequence is not available. -# -do_test reindex-3.1 { - sqlite3 db2 test.db - catchsql { - REINDEX c1; - } db2 -} {1 {no such collation sequence: c1}} -do_test reindex-3.2 { - proc need_collate {collation} { - db2 collate c1 c1 - } - db2 collation_needed need_collate - catchsql { - REINDEX c1; - } db2 -} {0 {}} -do_test reindex-3.3 { - catchsql { - REINDEX; - } db2 -} {1 {no such collation sequence: c2}} - -do_test reindex-3.99 { - db2 close -} {} - -finish_test - diff --git a/sqlite/test/rollback.test b/sqlite/test/rollback.test deleted file mode 100644 index b73400f..0000000 --- a/sqlite/test/rollback.test +++ /dev/null @@ -1,78 +0,0 @@ -# 2004 June 30 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this file is verifying that a rollback in one statement -# caused by an ON CONFLICT ROLLBACK clause aborts any other pending -# statements. -# -# $Id: rollback.test,v 1.2 2005/01/12 13:04:55 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -db close -set DB [sqlite3 db test.db] - -do_test rollback-1.1 { - execsql { - CREATE TABLE t1(a); - INSERT INTO t1 VALUES(1); - INSERT INTO t1 VALUES(2); - INSERT INTO t1 VALUES(3); - INSERT INTO t1 VALUES(4); - SELECT * FROM t1; - } -} {1 2 3 4} - -do_test rollback-1.2 { - execsql { - CREATE TABLE t3(a unique on conflict rollback); - INSERT INTO t3 SELECT a FROM t1; - BEGIN; - INSERT INTO t1 SELECT * FROM t1; - } -} {} -do_test rollback-1.3 { - set STMT [sqlite3_prepare $DB "SELECT a FROM t1" -1 TAIL] - sqlite3_step $STMT -} {SQLITE_ROW} - -# This causes a ROLLBACK, which deletes the table out from underneath the -# SELECT statement. -# -do_test rollback-1.4 { - catchsql { - INSERT INTO t3 SELECT a FROM t1; - } -} {1 {column a is not unique}} - -# Try to continue with the SELECT statement -# -do_test rollback-1.5 { - sqlite3_step $STMT -} {SQLITE_ABORT} - -# Restart the SELECT statement -# -do_test rollback-1.6 { - sqlite3_reset $STMT -} {SQLITE_OK} -do_test rollback-1.7 { - sqlite3_step $STMT -} {SQLITE_ROW} -do_test rollback-1.8 { - sqlite3_step $STMT -} {SQLITE_ROW} -do_test rollback-1.9 { - sqlite3_finalize $STMT -} {SQLITE_OK} - -finish_test diff --git a/sqlite/test/rowid.test b/sqlite/test/rowid.test deleted file mode 100644 index 96091a5..0000000 --- a/sqlite/test/rowid.test +++ /dev/null @@ -1,674 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the magic ROWID column that is -# found on all tables. -# -# $Id: rowid.test,v 1.18 2005/01/21 03:12:16 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Basic ROWID functionality tests. -# -do_test rowid-1.1 { - execsql { - CREATE TABLE t1(x int, y int); - INSERT INTO t1 VALUES(1,2); - INSERT INTO t1 VALUES(3,4); - SELECT x FROM t1 ORDER BY y; - } -} {1 3} -do_test rowid-1.2 { - set r [execsql {SELECT rowid FROM t1 ORDER BY x}] - global x2rowid rowid2x - set x2rowid(1) [lindex $r 0] - set x2rowid(3) [lindex $r 1] - set rowid2x($x2rowid(1)) 1 - set rowid2x($x2rowid(3)) 3 - llength $r -} {2} -do_test rowid-1.3 { - global x2rowid - set sql "SELECT x FROM t1 WHERE rowid==$x2rowid(1)" - execsql $sql -} {1} -do_test rowid-1.4 { - global x2rowid - set sql "SELECT x FROM t1 WHERE rowid==$x2rowid(3)" - execsql $sql -} {3} -do_test rowid-1.5 { - global x2rowid - set sql "SELECT x FROM t1 WHERE oid==$x2rowid(1)" - execsql $sql -} {1} -do_test rowid-1.6 { - global x2rowid - set sql "SELECT x FROM t1 WHERE OID==$x2rowid(3)" - execsql $sql -} {3} -do_test rowid-1.7 { - global x2rowid - set sql "SELECT x FROM t1 WHERE _rowid_==$x2rowid(1)" - execsql $sql -} {1} -do_test rowid-1.7.1 { - while 1 { - set norow [expr {int(rand()*1000000)}] - if {$norow!=$x2rowid(1) && $norow!=$x2rowid(3)} break - } - execsql "SELECT x FROM t1 WHERE rowid=$norow" -} {} -do_test rowid-1.8 { - global x2rowid - set v [execsql {SELECT x, oid FROM t1 order by x}] - set v2 [list 1 $x2rowid(1) 3 $x2rowid(3)] - expr {$v==$v2} -} {1} -do_test rowid-1.9 { - global x2rowid - set v [execsql {SELECT x, RowID FROM t1 order by x}] - set v2 [list 1 $x2rowid(1) 3 $x2rowid(3)] - expr {$v==$v2} -} {1} -do_test rowid-1.9 { - global x2rowid - set v [execsql {SELECT x, _rowid_ FROM t1 order by x}] - set v2 [list 1 $x2rowid(1) 3 $x2rowid(3)] - expr {$v==$v2} -} {1} - -# We can insert or update the ROWID column. -# -do_test rowid-2.1 { - catchsql { - INSERT INTO t1(rowid,x,y) VALUES(1234,5,6); - SELECT rowid, * FROM t1; - } -} {0 {1 1 2 2 3 4 1234 5 6}} -do_test rowid-2.2 { - catchsql { - UPDATE t1 SET rowid=12345 WHERE x==1; - SELECT rowid, * FROM t1 - } -} {0 {2 3 4 1234 5 6 12345 1 2}} -do_test rowid-2.3 { - catchsql { - INSERT INTO t1(y,x,oid) VALUES(8,7,1235); - SELECT rowid, * FROM t1 WHERE rowid>1000; - } -} {0 {1234 5 6 1235 7 8 12345 1 2}} -do_test rowid-2.4 { - catchsql { - UPDATE t1 SET oid=12346 WHERE x==1; - SELECT rowid, * FROM t1; - } -} {0 {2 3 4 1234 5 6 1235 7 8 12346 1 2}} -do_test rowid-2.5 { - catchsql { - INSERT INTO t1(x,_rowid_,y) VALUES(9,1236,10); - SELECT rowid, * FROM t1 WHERE rowid>1000; - } -} {0 {1234 5 6 1235 7 8 1236 9 10 12346 1 2}} -do_test rowid-2.6 { - catchsql { - UPDATE t1 SET _rowid_=12347 WHERE x==1; - SELECT rowid, * FROM t1 WHERE rowid>1000; - } -} {0 {1234 5 6 1235 7 8 1236 9 10 12347 1 2}} - -# But we can use ROWID in the WHERE clause of an UPDATE that does not -# change the ROWID. -# -do_test rowid-2.7 { - global x2rowid - set sql "UPDATE t1 SET x=2 WHERE OID==$x2rowid(3)" - execsql $sql - execsql {SELECT x FROM t1 ORDER BY x} -} {1 2 5 7 9} -do_test rowid-2.8 { - global x2rowid - set sql "UPDATE t1 SET x=3 WHERE _rowid_==$x2rowid(3)" - execsql $sql - execsql {SELECT x FROM t1 ORDER BY x} -} {1 3 5 7 9} - -# We cannot index by ROWID -# -do_test rowid-2.9 { - set v [catch {execsql {CREATE INDEX idxt1 ON t1(rowid)}} msg] - lappend v $msg -} {1 {table t1 has no column named rowid}} -do_test rowid-2.10 { - set v [catch {execsql {CREATE INDEX idxt1 ON t1(_rowid_)}} msg] - lappend v $msg -} {1 {table t1 has no column named _rowid_}} -do_test rowid-2.11 { - set v [catch {execsql {CREATE INDEX idxt1 ON t1(oid)}} msg] - lappend v $msg -} {1 {table t1 has no column named oid}} -do_test rowid-2.12 { - set v [catch {execsql {CREATE INDEX idxt1 ON t1(x, rowid)}} msg] - lappend v $msg -} {1 {table t1 has no column named rowid}} - -# Columns defined in the CREATE statement override the buildin ROWID -# column names. -# -do_test rowid-3.1 { - execsql { - CREATE TABLE t2(rowid int, x int, y int); - INSERT INTO t2 VALUES(0,2,3); - INSERT INTO t2 VALUES(4,5,6); - INSERT INTO t2 VALUES(7,8,9); - SELECT * FROM t2 ORDER BY x; - } -} {0 2 3 4 5 6 7 8 9} -do_test rowid-3.2 { - execsql {SELECT * FROM t2 ORDER BY rowid} -} {0 2 3 4 5 6 7 8 9} -do_test rowid-3.3 { - execsql {SELECT rowid, x, y FROM t2 ORDER BY rowid} -} {0 2 3 4 5 6 7 8 9} -do_test rowid-3.4 { - set r1 [execsql {SELECT _rowid_, rowid FROM t2 ORDER BY rowid}] - foreach {a b c d e f} $r1 {} - set r2 [execsql {SELECT _rowid_, rowid FROM t2 ORDER BY x DESC}] - foreach {u v w x y z} $r2 {} - expr {$u==$e && $w==$c && $y==$a} -} {1} -# sqlite3 v3 - do_probtest doesn't exist anymore? -if 0 { -do_probtest rowid-3.5 { - set r1 [execsql {SELECT _rowid_, rowid FROM t2 ORDER BY rowid}] - foreach {a b c d e f} $r1 {} - expr {$a!=$b && $c!=$d && $e!=$f} -} {1} -} - -# Let's try some more complex examples, including some joins. -# -do_test rowid-4.1 { - execsql { - DELETE FROM t1; - DELETE FROM t2; - } - for {set i 1} {$i<=50} {incr i} { - execsql "INSERT INTO t1(x,y) VALUES($i,[expr {$i*$i}])" - } - execsql {INSERT INTO t2 SELECT _rowid_, x*y, y*y FROM t1} - execsql {SELECT t2.y FROM t1, t2 WHERE t1.x==4 AND t1.rowid==t2.rowid} -} {256} -do_test rowid-4.2 { - execsql {SELECT t2.y FROM t2, t1 WHERE t1.x==4 AND t1.rowid==t2.rowid} -} {256} -do_test rowid-4.2.1 { - execsql {SELECT t2.y FROM t2, t1 WHERE t1.x==4 AND t1.oid==t2.rowid} -} {256} -do_test rowid-4.2.2 { - execsql {SELECT t2.y FROM t2, t1 WHERE t1.x==4 AND t1._rowid_==t2.rowid} -} {256} -do_test rowid-4.2.3 { - execsql {SELECT t2.y FROM t2, t1 WHERE t1.x==4 AND t2.rowid==t1.rowid} -} {256} -do_test rowid-4.2.4 { - execsql {SELECT t2.y FROM t2, t1 WHERE t2.rowid==t1.oid AND t1.x==4} -} {256} -do_test rowid-4.2.5 { - execsql {SELECT t2.y FROM t1, t2 WHERE t1.x==4 AND t1._rowid_==t2.rowid} -} {256} -do_test rowid-4.2.6 { - execsql {SELECT t2.y FROM t1, t2 WHERE t1.x==4 AND t2.rowid==t1.rowid} -} {256} -do_test rowid-4.2.7 { - execsql {SELECT t2.y FROM t1, t2 WHERE t2.rowid==t1.oid AND t1.x==4} -} {256} -do_test rowid-4.3 { - execsql {CREATE INDEX idxt1 ON t1(x)} - execsql {SELECT t2.y FROM t1, t2 WHERE t1.x==4 AND t1.rowid==t2.rowid} -} {256} -do_test rowid-4.3.1 { - execsql {SELECT t2.y FROM t1, t2 WHERE t1.x==4 AND t1._rowid_==t2.rowid} -} {256} -do_test rowid-4.3.2 { - execsql {SELECT t2.y FROM t1, t2 WHERE t2.rowid==t1.oid AND 4==t1.x} -} {256} -do_test rowid-4.4 { - execsql {SELECT t2.y FROM t2, t1 WHERE t1.x==4 AND t1.rowid==t2.rowid} -} {256} -do_test rowid-4.4.1 { - execsql {SELECT t2.y FROM t2, t1 WHERE t1.x==4 AND t1._rowid_==t2.rowid} -} {256} -do_test rowid-4.4.2 { - execsql {SELECT t2.y FROM t2, t1 WHERE t2.rowid==t1.oid AND 4==t1.x} -} {256} -do_test rowid-4.5 { - execsql {CREATE INDEX idxt2 ON t2(y)} - set sqlite_search_count 0 - concat [execsql { - SELECT t1.x FROM t2, t1 - WHERE t2.y==256 AND t1.rowid==t2.rowid - }] $sqlite_search_count -} {4 3} -do_test rowid-4.5.1 { - set sqlite_search_count 0 - concat [execsql { - SELECT t1.x FROM t2, t1 - WHERE t1.OID==t2.rowid AND t2.y==81 - }] $sqlite_search_count -} {3 3} -do_test rowid-4.6 { - execsql { - SELECT t1.x FROM t1, t2 - WHERE t2.y==256 AND t1.rowid==t2.rowid - } -} {4} - -do_test rowid-5.1.1 { - ifcapable subquery { - execsql {DELETE FROM t1 WHERE _rowid_ IN (SELECT oid FROM t1 WHERE x>8)} - } else { - set oids [execsql {SELECT oid FROM t1 WHERE x>8}] - set where "_rowid_ = [join $oids { OR _rowid_ = }]" - execsql "DELETE FROM t1 WHERE $where" - } -} {} -do_test rowid-5.1.2 { - execsql {SELECT max(x) FROM t1} -} {8} - -# Make sure a "WHERE rowid=X" clause works when there is no ROWID of X. -# -do_test rowid-6.1 { - execsql { - SELECT x FROM t1 - } -} {1 2 3 4 5 6 7 8} -do_test rowid-6.2 { - for {set ::norow 1} {1} {incr ::norow} { - if {[execsql "SELECT x FROM t1 WHERE rowid=$::norow"]==""} break - } - execsql [subst { - DELETE FROM t1 WHERE rowid=$::norow - }] -} {} -do_test rowid-6.3 { - execsql { - SELECT x FROM t1 - } -} {1 2 3 4 5 6 7 8} - -# Beginning with version 2.3.4, SQLite computes rowids of new rows by -# finding the maximum current rowid and adding one. It falls back to -# the old random algorithm if the maximum rowid is the largest integer. -# The following tests are for this new behavior. -# -do_test rowid-7.0 { - execsql { - DELETE FROM t1; - DROP TABLE t2; - DROP INDEX idxt1; - INSERT INTO t1 VALUES(1,2); - SELECT rowid, * FROM t1; - } -} {1 1 2} -do_test rowid-7.1 { - execsql { - INSERT INTO t1 VALUES(99,100); - SELECT rowid,* FROM t1 - } -} {1 1 2 2 99 100} -do_test rowid-7.2 { - execsql { - CREATE TABLE t2(a INTEGER PRIMARY KEY, b); - INSERT INTO t2(b) VALUES(55); - SELECT * FROM t2; - } -} {1 55} -do_test rowid-7.3 { - execsql { - INSERT INTO t2(b) VALUES(66); - SELECT * FROM t2; - } -} {1 55 2 66} -do_test rowid-7.4 { - execsql { - INSERT INTO t2(a,b) VALUES(1000000,77); - INSERT INTO t2(b) VALUES(88); - SELECT * FROM t2; - } -} {1 55 2 66 1000000 77 1000001 88} -do_test rowid-7.5 { - execsql { - INSERT INTO t2(a,b) VALUES(2147483647,99); - INSERT INTO t2(b) VALUES(11); - SELECT b FROM t2 ORDER BY b; - } -} {11 55 66 77 88 99} -ifcapable subquery { - do_test rowid-7.6 { - execsql { - SELECT b FROM t2 WHERE a NOT IN(1,2,1000000,1000001,2147483647); - } - } {11} - do_test rowid-7.7 { - execsql { - INSERT INTO t2(b) VALUES(22); - INSERT INTO t2(b) VALUES(33); - INSERT INTO t2(b) VALUES(44); - INSERT INTO t2(b) VALUES(55); - SELECT b FROM t2 WHERE a NOT IN(1,2,1000000,1000001,2147483647) - ORDER BY b; - } - } {11 22 33 44 55} -} -do_test rowid-7.8 { - execsql { - DELETE FROM t2 WHERE a!=2; - INSERT INTO t2(b) VALUES(111); - SELECT * FROM t2; - } -} {2 66 3 111} - -ifcapable {trigger} { -# Make sure AFTER triggers that do INSERTs do not change the last_insert_rowid. -# Ticket #290 -# -do_test rowid-8.1 { - execsql { - CREATE TABLE t3(a integer primary key); - CREATE TABLE t4(x); - INSERT INTO t4 VALUES(1); - CREATE TRIGGER r3 AFTER INSERT on t3 FOR EACH ROW BEGIN - INSERT INTO t4 VALUES(NEW.a+10); - END; - SELECT * FROM t3; - } -} {} -do_test rowid-8.2 { - execsql { - SELECT rowid, * FROM t4; - } -} {1 1} -do_test rowid-8.3 { - execsql { - INSERT INTO t3 VALUES(123); - SELECT last_insert_rowid(); - } -} {123} -do_test rowid-8.4 { - execsql { - SELECT * FROM t3; - } -} {123} -do_test rowid-8.5 { - execsql { - SELECT rowid, * FROM t4; - } -} {1 1 2 133} -do_test rowid-8.6 { - execsql { - INSERT INTO t3 VALUES(NULL); - SELECT last_insert_rowid(); - } -} {124} -do_test rowid-8.7 { - execsql { - SELECT * FROM t3; - } -} {123 124} -do_test rowid-8.8 { - execsql { - SELECT rowid, * FROM t4; - } -} {1 1 2 133 3 134} -} ;# endif trigger - -# If triggers are not enable, simulate their effect for the tests that -# follow. -ifcapable {!trigger} { - execsql { - CREATE TABLE t3(a integer primary key); - INSERT INTO t3 VALUES(123); - INSERT INTO t3 VALUES(124); - } -} - -# ticket #377: Comparison between integer primiary key and floating point -# values. -# -do_test rowid-9.1 { - execsql { - SELECT * FROM t3 WHERE a<123.5 - } -} {123} -do_test rowid-9.2 { - execsql { - SELECT * FROM t3 WHERE a<124.5 - } -} {123 124} -do_test rowid-9.3 { - execsql { - SELECT * FROM t3 WHERE a>123.5 - } -} {124} -do_test rowid-9.4 { - execsql { - SELECT * FROM t3 WHERE a>122.5 - } -} {123 124} -do_test rowid-9.5 { - execsql { - SELECT * FROM t3 WHERE a==123.5 - } -} {} -do_test rowid-9.6 { - execsql { - SELECT * FROM t3 WHERE a==123.000 - } -} {123} -do_test rowid-9.7 { - execsql { - SELECT * FROM t3 WHERE a>100.5 AND a<200.5 - } -} {123 124} -do_test rowid-9.8 { - execsql { - SELECT * FROM t3 WHERE a>'xyz'; - } -} {} -do_test rowid-9.9 { - execsql { - SELECT * FROM t3 WHERE a<'xyz'; - } -} {123 124} -do_test rowid-9.10 { - execsql { - SELECT * FROM t3 WHERE a>=122.9 AND a<=123.1 - } -} {123} - -# Ticket #567. Comparisons of ROWID or integery primary key against -# floating point numbers still do not always work. -# -do_test rowid-10.1 { - execsql { - CREATE TABLE t5(a); - INSERT INTO t5 VALUES(1); - INSERT INTO t5 VALUES(2); - INSERT INTO t5 SELECT a+2 FROM t5; - INSERT INTO t5 SELECT a+4 FROM t5; - SELECT rowid, * FROM t5; - } -} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} -do_test rowid-10.2 { - execsql {SELECT rowid, a FROM t5 WHERE rowid>=5.5} -} {6 6 7 7 8 8} -do_test rowid-10.3 { - execsql {SELECT rowid, a FROM t5 WHERE rowid>=5.0} -} {5 5 6 6 7 7 8 8} -do_test rowid-10.4 { - execsql {SELECT rowid, a FROM t5 WHERE rowid>5.5} -} {6 6 7 7 8 8} -do_test rowid-10.3.2 { - execsql {SELECT rowid, a FROM t5 WHERE rowid>5.0} -} {6 6 7 7 8 8} -do_test rowid-10.5 { - execsql {SELECT rowid, a FROM t5 WHERE 5.5<=rowid} -} {6 6 7 7 8 8} -do_test rowid-10.6 { - execsql {SELECT rowid, a FROM t5 WHERE 5.5=rowid} -} {1 1 2 2 3 3 4 4 5 5} -do_test rowid-10.10 { - execsql {SELECT rowid, a FROM t5 WHERE 5.5>rowid} -} {1 1 2 2 3 3 4 4 5 5} -do_test rowid-10.11 { - execsql {SELECT rowid, a FROM t5 WHERE rowid>=5.5 ORDER BY rowid DESC} -} {8 8 7 7 6 6} -do_test rowid-10.11.2 { - execsql {SELECT rowid, a FROM t5 WHERE rowid>=5.0 ORDER BY rowid DESC} -} {8 8 7 7 6 6 5 5} -do_test rowid-10.12 { - execsql {SELECT rowid, a FROM t5 WHERE rowid>5.5 ORDER BY rowid DESC} -} {8 8 7 7 6 6} -do_test rowid-10.12.2 { - execsql {SELECT rowid, a FROM t5 WHERE rowid>5.0 ORDER BY rowid DESC} -} {8 8 7 7 6 6} -do_test rowid-10.13 { - execsql {SELECT rowid, a FROM t5 WHERE 5.5<=rowid ORDER BY rowid DESC} -} {8 8 7 7 6 6} -do_test rowid-10.14 { - execsql {SELECT rowid, a FROM t5 WHERE 5.5=rowid ORDER BY rowid DESC} -} {5 5 4 4 3 3 2 2 1 1} -do_test rowid-10.18 { - execsql {SELECT rowid, a FROM t5 WHERE 5.5>rowid ORDER BY rowid DESC} -} {5 5 4 4 3 3 2 2 1 1} - -do_test rowid-10.30 { - execsql { - CREATE TABLE t6(a); - INSERT INTO t6(rowid,a) SELECT -a,a FROM t5; - SELECT rowid, * FROM t6; - } -} {-8 8 -7 7 -6 6 -5 5 -4 4 -3 3 -2 2 -1 1} -do_test rowid-10.31.1 { - execsql {SELECT rowid, a FROM t6 WHERE rowid>=-5.5} -} {-5 5 -4 4 -3 3 -2 2 -1 1} -do_test rowid-10.31.2 { - execsql {SELECT rowid, a FROM t6 WHERE rowid>=-5.0} -} {-5 5 -4 4 -3 3 -2 2 -1 1} -do_test rowid-10.32.1 { - execsql {SELECT rowid, a FROM t6 WHERE rowid>=-5.5 ORDER BY rowid DESC} -} {-1 1 -2 2 -3 3 -4 4 -5 5} -do_test rowid-10.32.1 { - execsql {SELECT rowid, a FROM t6 WHERE rowid>=-5.0 ORDER BY rowid DESC} -} {-1 1 -2 2 -3 3 -4 4 -5 5} -do_test rowid-10.33 { - execsql {SELECT rowid, a FROM t6 WHERE -5.5<=rowid} -} {-5 5 -4 4 -3 3 -2 2 -1 1} -do_test rowid-10.34 { - execsql {SELECT rowid, a FROM t6 WHERE -5.5<=rowid ORDER BY rowid DESC} -} {-1 1 -2 2 -3 3 -4 4 -5 5} -do_test rowid-10.35.1 { - execsql {SELECT rowid, a FROM t6 WHERE rowid>-5.5} -} {-5 5 -4 4 -3 3 -2 2 -1 1} -do_test rowid-10.35.2 { - execsql {SELECT rowid, a FROM t6 WHERE rowid>-5.0} -} {-4 4 -3 3 -2 2 -1 1} -do_test rowid-10.36.1 { - execsql {SELECT rowid, a FROM t6 WHERE rowid>-5.5 ORDER BY rowid DESC} -} {-1 1 -2 2 -3 3 -4 4 -5 5} -do_test rowid-10.36.2 { - execsql {SELECT rowid, a FROM t6 WHERE rowid>-5.0 ORDER BY rowid DESC} -} {-1 1 -2 2 -3 3 -4 4} -do_test rowid-10.37 { - execsql {SELECT rowid, a FROM t6 WHERE -5.5=rowid} -} {-8 8 -7 7 -6 6} -do_test rowid-10.42 { - execsql {SELECT rowid, a FROM t6 WHERE -5.5>=rowid ORDER BY rowid DESC} -} {-6 6 -7 7 -8 8} -do_test rowid-10.43 { - execsql {SELECT rowid, a FROM t6 WHERE rowid<-5.5} -} {-8 8 -7 7 -6 6} -do_test rowid-10.44 { - execsql {SELECT rowid, a FROM t6 WHERE rowid<-5.5 ORDER BY rowid DESC} -} {-6 6 -7 7 -8 8} -do_test rowid-10.44 { - execsql {SELECT rowid, a FROM t6 WHERE -5.5>rowid} -} {-8 8 -7 7 -6 6} -do_test rowid-10.46 { - execsql {SELECT rowid, a FROM t6 WHERE -5.5>rowid ORDER BY rowid DESC} -} {-6 6 -7 7 -8 8} - -# Comparison of rowid against string values. -# -do_test rowid-11.1 { - execsql {SELECT rowid, a FROM t5 WHERE rowid>'abc'} -} {} -do_test rowid-11.2 { - execsql {SELECT rowid, a FROM t5 WHERE rowid>='abc'} -} {} -do_test rowid-11.3 { - execsql {SELECT rowid, a FROM t5 WHERE rowid<'abc'} -} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} -do_test rowid-11.4 { - execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc'} -} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} - -# Test the automatic generation of rowids when the table already contains -# a rowid with the maximum value. -# -do_test rowid-12.1 { - execsql { - CREATE TABLE t7(x INTEGER PRIMARY KEY, y); - INSERT INTO t7 VALUES(9223372036854775807,'a'); - SELECT y FROM t7; - } -} {a} -do_test rowid-12.2 { - execsql { - INSERT INTO t7 VALUES(NULL,'b'); - SELECT y FROM t7; - } -} {b a} - -finish_test diff --git a/sqlite/test/safety.test b/sqlite/test/safety.test deleted file mode 100644 index a12cd84..0000000 --- a/sqlite/test/safety.test +++ /dev/null @@ -1,69 +0,0 @@ -# 2005 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 implements regression tests for SQLite library. The -# focus of this file is testing the sqlite3SafetyOn and sqlite3SafetyOff -# functions. Those routines are not strictly necessary - they are -# designed to detect misuse of the library. -# -# $Id: safety.test,v 1.1 2005/01/11 15:28:33 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -do_test safety-1.1 { - db close - set DB [sqlite3 db test.db] - db eval {CREATE TABLE t1(a)} - sqlite_set_magic $DB SQLITE_MAGIC_BUSY - catchsql { - SELECT name FROM sqlite_master; - } -} {1 {library routine called out of sequence}} -do_test safety-1.2 { - sqlite_set_magic $DB SQLITE_MAGIC_OPEN - catchsql { - SELECT name FROM sqlite_master - } -} {0 t1} - -do_test safety-2.1 { - proc safety_on {} "sqlite_set_magic $DB SQLITE_MAGIC_BUSY" - db function safety_on safety_on - catchsql { - SELECT safety_on(), name FROM sqlite_master - } -} {1 {library routine called out of sequence}} -do_test safety-2.2 { - catchsql { - SELECT 'hello' - } -} {1 {library routine called out of sequence}} -do_test safety-2.3 { - sqlite3_close $DB -} {SQLITE_MISUSE} -do_test safety-2.4 { - sqlite_set_magic $DB SQLITE_MAGIC_OPEN - execsql { - SELECT name FROM sqlite_master - } -} {t1} - -do_test safety-3.1 { - set rc [catch { - db eval {SELECT name FROM sqlite_master} { - sqlite_set_magic $DB SQLITE_MAGIC_BUSY - } - } msg] - lappend rc $msg -} {1 {library routine called out of sequence}} -sqlite_set_magic $DB SQLITE_MAGIC_OPEN - -finish_test diff --git a/sqlite/test/schema.test b/sqlite/test/schema.test deleted file mode 100644 index 76783b5..0000000 --- a/sqlite/test/schema.test +++ /dev/null @@ -1,336 +0,0 @@ -# 2005 Jan 24 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# -# This file tests the various conditions under which an SQLITE_SCHEMA -# error should be returned. -# -# $Id: schema.test,v 1.4 2005/01/29 01:54:18 danielk1977 Exp $ - -#--------------------------------------------------------------------- -# When any of the following types of SQL statements or actions are -# executed, all pre-compiled statements are invalidated. An attempt -# to execute an invalidated statement always returns SQLITE_SCHEMA. -# -# CREATE/DROP TABLE...................................schema-1.* -# CREATE/DROP VIEW....................................schema-2.* -# CREATE/DROP TRIGGER.................................schema-3.* -# CREATE/DROP INDEX...................................schema-4.* -# DETACH..............................................schema-5.* -# Deleting a user-function............................schema-6.* -# Deleting a collation sequence.......................schema-7.* -# Setting or changing the authorization function......schema-8.* -# -# Note: Test cases schema-6.* are missing right now. -# -# Test cases schema-9.* and schema-10.* test some specific bugs -# that came up during development. -# -# Test cases schema-11.* test that it is impossible to delete or -# change a collation sequence or user-function while SQL statements -# are executing. Adding new collations or functions is allowed. -# -# Note: Test cases schema-11.* are also missing right now. - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -do_test schema-1.1 { - set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] - execsql { - CREATE TABLE abc(a, b, c); - } - sqlite3_step $::STMT -} {SQLITE_ERROR} -do_test schema-1.2 { - sqlite3_finalize $::STMT -} {SQLITE_SCHEMA} -do_test schema-1.3 { - set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] - execsql { - DROP TABLE abc; - } - sqlite3_step $::STMT -} {SQLITE_ERROR} -do_test schema-1.4 { - sqlite3_finalize $::STMT -} {SQLITE_SCHEMA} - -ifcapable view { - do_test schema-2.1 { - set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] - execsql { - CREATE VIEW v1 AS SELECT * FROM sqlite_master; - } - sqlite3_step $::STMT - } {SQLITE_ERROR} - do_test schema-2.2 { - sqlite3_finalize $::STMT - } {SQLITE_SCHEMA} - do_test schema-2.3 { - set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] - execsql { - DROP VIEW v1; - } - sqlite3_step $::STMT - } {SQLITE_ERROR} - do_test schema-2.4 { - sqlite3_finalize $::STMT - } {SQLITE_SCHEMA} -} - -ifcapable trigger { - do_test schema-3.1 { - execsql { - CREATE TABLE abc(a, b, c); - } - set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] - execsql { - CREATE TRIGGER abc_trig AFTER INSERT ON abc BEGIN - SELECT 1, 2, 3; - END; - } - sqlite3_step $::STMT - } {SQLITE_ERROR} - do_test schema-3.2 { - sqlite3_finalize $::STMT - } {SQLITE_SCHEMA} - do_test schema-3.3 { - set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] - execsql { - DROP TRIGGER abc_trig; - } - sqlite3_step $::STMT - } {SQLITE_ERROR} - do_test schema-3.4 { - sqlite3_finalize $::STMT - } {SQLITE_SCHEMA} -} - -do_test schema-4.1 { - catchsql { - CREATE TABLE abc(a, b, c); - } - set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] - execsql { - CREATE INDEX abc_index ON abc(a); - } - sqlite3_step $::STMT -} {SQLITE_ERROR} -do_test schema-4.2 { - sqlite3_finalize $::STMT -} {SQLITE_SCHEMA} -do_test schema-4.3 { - set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] - execsql { - DROP INDEX abc_index; - } - sqlite3_step $::STMT -} {SQLITE_ERROR} -do_test schema-4.4 { - sqlite3_finalize $::STMT -} {SQLITE_SCHEMA} - -#--------------------------------------------------------------------- -# Tests 5.1 to 5.4 check that prepared statements are invalidated when -# a database is DETACHed (but not when one is ATTACHed). -# -do_test schema-5.1 { - set sql {SELECT * FROM abc;} - set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL] - execsql { - ATTACH 'test2.db' AS aux; - } - sqlite3_step $::STMT -} {SQLITE_DONE} -do_test schema-5.2 { - sqlite3_reset $::STMT -} {SQLITE_OK} -do_test schema-5.3 { - execsql { - DETACH aux; - } - sqlite3_step $::STMT -} {SQLITE_ERROR} -do_test schema-5.4 { - sqlite3_finalize $::STMT -} {SQLITE_SCHEMA} - -#--------------------------------------------------------------------- -# Tests 6.* check that prepared statements are invalidated when -# a user-function is deleted (but not when one is added). -do_test schema-6.1 { - set sql {SELECT * FROM abc;} - set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL] - db function hello_function {} - sqlite3_step $::STMT -} {SQLITE_DONE} -do_test schema-6.2 { - sqlite3_reset $::STMT -} {SQLITE_OK} -do_test schema-6.3 { - sqlite_delete_function $::DB hello_function - sqlite3_step $::STMT -} {SQLITE_ERROR} -do_test schema-6.4 { - sqlite3_finalize $::STMT -} {SQLITE_SCHEMA} - -#--------------------------------------------------------------------- -# Tests 7.* check that prepared statements are invalidated when -# a collation sequence is deleted (but not when one is added). -# -ifcapable utf16 { - do_test schema-7.1 { - set sql {SELECT * FROM abc;} - set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL] - add_test_collate $::DB 1 1 1 - sqlite3_step $::STMT - } {SQLITE_DONE} - do_test schema-7.2 { - sqlite3_reset $::STMT - } {SQLITE_OK} - do_test schema-7.3 { - add_test_collate $::DB 0 0 0 - sqlite3_step $::STMT - } {SQLITE_ERROR} - do_test schema-7.4 { - sqlite3_finalize $::STMT - } {SQLITE_SCHEMA} -} - -#--------------------------------------------------------------------- -# Tests 8.1 and 8.2 check that prepared statements are invalidated when -# the authorization function is set. -# -ifcapable auth { - do_test schema-8.1 { - set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] - db auth {} - sqlite3_step $::STMT - } {SQLITE_ERROR} - do_test schema-8.3 { - sqlite3_finalize $::STMT - } {SQLITE_SCHEMA} -} - -#--------------------------------------------------------------------- -# schema-9.1: Test that if a table is dropped by one database connection, -# other database connections are aware of the schema change. -# schema-9.2: Test that if a view is dropped by one database connection, -# other database connections are aware of the schema change. -# -do_test schema-9.1 { - sqlite3 db2 test.db - execsql { - DROP TABLE abc; - } db2 - db2 close - catchsql { - SELECT * FROM abc; - } -} {1 {no such table: abc}} -execsql { - CREATE TABLE abc(a, b, c); -} -ifcapable view { - do_test schema-9.2 { - execsql { - CREATE VIEW abcview AS SELECT * FROM abc; - } - sqlite3 db2 test.db - execsql { - DROP VIEW abcview; - } db2 - db2 close - catchsql { - SELECT * FROM abcview; - } - } {1 {no such table: abcview}} -} - -#--------------------------------------------------------------------- -# Test that if a CREATE TABLE statement fails because there are other -# btree cursors open on the same database file it does not corrupt -# the sqlite_master table. -# -do_test schema-10.1 { - execsql { - INSERT INTO abc VALUES(1, 2, 3); - } - set sql {SELECT * FROM abc} - set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL] - sqlite3_step $::STMT -} {SQLITE_ROW} -do_test schema-10.2 { - catchsql { - CREATE TABLE t2(a, b, c); - } -} {1 {database table is locked}} -do_test schema-10.3 { - sqlite3_finalize $::STMT -} {SQLITE_OK} -do_test schema-10.4 { - sqlite3 db2 test.db - execsql { - SELECT * FROM abc - } db2 -} {1 2 3} -do_test schema-10.5 { - db2 close -} {} - -#--------------------------------------------------------------------- -# Attempting to delete or replace a user-function or collation sequence -# while there are active statements returns an SQLITE_BUSY error. -# -# schema-11.1 - 11.4: User function. -# schema-11.5 - 11.8: Collation sequence. -# -do_test schema-11.1 { - db function tstfunc {} - set sql {SELECT * FROM abc} - set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL] - sqlite3_step $::STMT -} {SQLITE_ROW} -do_test schema-11.2 { - sqlite_delete_function $::DB tstfunc -} {SQLITE_BUSY} -do_test schema-11.3 { - set rc [catch { - db function tstfunc {} - } msg] - list $rc $msg -} {1 {Unable to delete/modify user-function due to active statements}} -do_test schema-11.4 { - sqlite3_finalize $::STMT -} {SQLITE_OK} -do_test schema-11.5 { - db collate tstcollate {} - set sql {SELECT * FROM abc} - set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL] - sqlite3_step $::STMT -} {SQLITE_ROW} -do_test schema-11.6 { - sqlite_delete_collation $::DB tstcollate -} {SQLITE_BUSY} -do_test schema-11.7 { - set rc [catch { - db collate tstcollate {} - } msg] - list $rc $msg -} {1 {Unable to delete/modify collation sequence due to active statements}} -do_test schema-11.8 { - sqlite3_finalize $::STMT -} {SQLITE_OK} - -finish_test - diff --git a/sqlite/test/select1.test b/sqlite/test/select1.test deleted file mode 100644 index 0f12ecf..0000000 --- a/sqlite/test/select1.test +++ /dev/null @@ -1,803 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the SELECT statement. -# -# $Id: select1.test,v 1.42 2005/01/21 04:25:47 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Try to select on a non-existant table. -# -do_test select1-1.1 { - set v [catch {execsql {SELECT * FROM test1}} msg] - lappend v $msg -} {1 {no such table: test1}} - -execsql {CREATE TABLE test1(f1 int, f2 int)} - -do_test select1-1.2 { - set v [catch {execsql {SELECT * FROM test1, test2}} msg] - lappend v $msg -} {1 {no such table: test2}} -do_test select1-1.3 { - set v [catch {execsql {SELECT * FROM test2, test1}} msg] - lappend v $msg -} {1 {no such table: test2}} - -execsql {INSERT INTO test1(f1,f2) VALUES(11,22)} - - -# Make sure the columns are extracted correctly. -# -do_test select1-1.4 { - execsql {SELECT f1 FROM test1} -} {11} -do_test select1-1.5 { - execsql {SELECT f2 FROM test1} -} {22} -do_test select1-1.6 { - execsql {SELECT f2, f1 FROM test1} -} {22 11} -do_test select1-1.7 { - execsql {SELECT f1, f2 FROM test1} -} {11 22} -do_test select1-1.8 { - execsql {SELECT * FROM test1} -} {11 22} -do_test select1-1.8.1 { - execsql {SELECT *, * FROM test1} -} {11 22 11 22} -do_test select1-1.8.2 { - execsql {SELECT *, min(f1,f2), max(f1,f2) FROM test1} -} {11 22 11 22} -do_test select1-1.8.3 { - execsql {SELECT 'one', *, 'two', * FROM test1} -} {one 11 22 two 11 22} - -execsql {CREATE TABLE test2(r1 real, r2 real)} -execsql {INSERT INTO test2(r1,r2) VALUES(1.1,2.2)} - -do_test select1-1.9 { - execsql {SELECT * FROM test1, test2} -} {11 22 1.1 2.2} -do_test select1-1.9.1 { - execsql {SELECT *, 'hi' FROM test1, test2} -} {11 22 1.1 2.2 hi} -do_test select1-1.9.2 { - execsql {SELECT 'one', *, 'two', * FROM test1, test2} -} {one 11 22 1.1 2.2 two 11 22 1.1 2.2} -do_test select1-1.10 { - execsql {SELECT test1.f1, test2.r1 FROM test1, test2} -} {11 1.1} -do_test select1-1.11 { - execsql {SELECT test1.f1, test2.r1 FROM test2, test1} -} {11 1.1} -do_test select1-1.11.1 { - execsql {SELECT * FROM test2, test1} -} {1.1 2.2 11 22} -do_test select1-1.11.2 { - execsql {SELECT * FROM test1 AS a, test1 AS b} -} {11 22 11 22} -do_test select1-1.12 { - execsql {SELECT max(test1.f1,test2.r1), min(test1.f2,test2.r2) - FROM test2, test1} -} {11 2.2} -do_test select1-1.13 { - execsql {SELECT min(test1.f1,test2.r1), max(test1.f2,test2.r2) - FROM test1, test2} -} {1.1 22} - -set long {This is a string that is too big to fit inside a NBFS buffer} -do_test select1-2.0 { - execsql " - DROP TABLE test2; - DELETE FROM test1; - INSERT INTO test1 VALUES(11,22); - INSERT INTO test1 VALUES(33,44); - CREATE TABLE t3(a,b); - INSERT INTO t3 VALUES('abc',NULL); - INSERT INTO t3 VALUES(NULL,'xyz'); - INSERT INTO t3 SELECT * FROM test1; - CREATE TABLE t4(a,b); - INSERT INTO t4 VALUES(NULL,'$long'); - SELECT * FROM t3; - " -} {abc {} {} xyz 11 22 33 44} - -# Error messges from sqliteExprCheck -# -do_test select1-2.1 { - set v [catch {execsql {SELECT count(f1,f2) FROM test1}} msg] - lappend v $msg -} {1 {wrong number of arguments to function count()}} -do_test select1-2.2 { - set v [catch {execsql {SELECT count(f1) FROM test1}} msg] - lappend v $msg -} {0 2} -do_test select1-2.3 { - set v [catch {execsql {SELECT Count() FROM test1}} msg] - lappend v $msg -} {0 2} -do_test select1-2.4 { - set v [catch {execsql {SELECT COUNT(*) FROM test1}} msg] - lappend v $msg -} {0 2} -do_test select1-2.5 { - set v [catch {execsql {SELECT COUNT(*)+1 FROM test1}} msg] - lappend v $msg -} {0 3} -do_test select1-2.5.1 { - execsql {SELECT count(*),count(a),count(b) FROM t3} -} {4 3 3} -do_test select1-2.5.2 { - execsql {SELECT count(*),count(a),count(b) FROM t4} -} {1 0 1} -do_test select1-2.5.3 { - execsql {SELECT count(*),count(a),count(b) FROM t4 WHERE b=5} -} {0 0 0} -do_test select1-2.6 { - set v [catch {execsql {SELECT min(*) FROM test1}} msg] - lappend v $msg -} {1 {wrong number of arguments to function min()}} -do_test select1-2.7 { - set v [catch {execsql {SELECT Min(f1) FROM test1}} msg] - lappend v $msg -} {0 11} -do_test select1-2.8 { - set v [catch {execsql {SELECT MIN(f1,f2) FROM test1}} msg] - lappend v [lsort $msg] -} {0 {11 33}} -do_test select1-2.8.1 { - execsql {SELECT coalesce(min(a),'xyzzy') FROM t3} -} {11} -do_test select1-2.8.2 { - execsql {SELECT min(coalesce(a,'xyzzy')) FROM t3} -} {11} -do_test select1-2.8.3 { - execsql {SELECT min(b), min(b) FROM t4} -} [list $long $long] -do_test select1-2.9 { - set v [catch {execsql {SELECT MAX(*) FROM test1}} msg] - lappend v $msg -} {1 {wrong number of arguments to function MAX()}} -do_test select1-2.10 { - set v [catch {execsql {SELECT Max(f1) FROM test1}} msg] - lappend v $msg -} {0 33} -do_test select1-2.11 { - set v [catch {execsql {SELECT max(f1,f2) FROM test1}} msg] - lappend v [lsort $msg] -} {0 {22 44}} -do_test select1-2.12 { - set v [catch {execsql {SELECT MAX(f1,f2)+1 FROM test1}} msg] - lappend v [lsort $msg] -} {0 {23 45}} -do_test select1-2.13 { - set v [catch {execsql {SELECT MAX(f1)+1 FROM test1}} msg] - lappend v $msg -} {0 34} -do_test select1-2.13.1 { - execsql {SELECT coalesce(max(a),'xyzzy') FROM t3} -} {abc} -do_test select1-2.13.2 { - execsql {SELECT max(coalesce(a,'xyzzy')) FROM t3} -} {xyzzy} -do_test select1-2.14 { - set v [catch {execsql {SELECT SUM(*) FROM test1}} msg] - lappend v $msg -} {1 {wrong number of arguments to function SUM()}} -do_test select1-2.15 { - set v [catch {execsql {SELECT Sum(f1) FROM test1}} msg] - lappend v $msg -} {0 44.0} -do_test select1-2.16 { - set v [catch {execsql {SELECT sum(f1,f2) FROM test1}} msg] - lappend v $msg -} {1 {wrong number of arguments to function sum()}} -do_test select1-2.17 { - set v [catch {execsql {SELECT SUM(f1)+1 FROM test1}} msg] - lappend v $msg -} {0 45.0} -do_test select1-2.17.1 { - execsql {SELECT sum(a) FROM t3} -} {44.0} -do_test select1-2.18 { - set v [catch {execsql {SELECT XYZZY(f1) FROM test1}} msg] - lappend v $msg -} {1 {no such function: XYZZY}} -do_test select1-2.19 { - set v [catch {execsql {SELECT SUM(min(f1,f2)) FROM test1}} msg] - lappend v $msg -} {0 44.0} -do_test select1-2.20 { - set v [catch {execsql {SELECT SUM(min(f1)) FROM test1}} msg] - lappend v $msg -} {1 {misuse of aggregate function min()}} - -# WHERE clause expressions -# -do_test select1-3.1 { - set v [catch {execsql {SELECT f1 FROM test1 WHERE f1<11}} msg] - lappend v $msg -} {0 {}} -do_test select1-3.2 { - set v [catch {execsql {SELECT f1 FROM test1 WHERE f1<=11}} msg] - lappend v $msg -} {0 11} -do_test select1-3.3 { - set v [catch {execsql {SELECT f1 FROM test1 WHERE f1=11}} msg] - lappend v $msg -} {0 11} -do_test select1-3.4 { - set v [catch {execsql {SELECT f1 FROM test1 WHERE f1>=11}} msg] - lappend v [lsort $msg] -} {0 {11 33}} -do_test select1-3.5 { - set v [catch {execsql {SELECT f1 FROM test1 WHERE f1>11}} msg] - lappend v [lsort $msg] -} {0 33} -do_test select1-3.6 { - set v [catch {execsql {SELECT f1 FROM test1 WHERE f1!=11}} msg] - lappend v [lsort $msg] -} {0 33} -do_test select1-3.7 { - set v [catch {execsql {SELECT f1 FROM test1 WHERE min(f1,f2)!=11}} msg] - lappend v [lsort $msg] -} {0 33} -do_test select1-3.8 { - set v [catch {execsql {SELECT f1 FROM test1 WHERE max(f1,f2)!=11}} msg] - lappend v [lsort $msg] -} {0 {11 33}} -do_test select1-3.9 { - set v [catch {execsql {SELECT f1 FROM test1 WHERE count(f1,f2)!=11}} msg] - lappend v $msg -} {1 {wrong number of arguments to function count()}} - -# ORDER BY expressions -# -do_test select1-4.1 { - set v [catch {execsql {SELECT f1 FROM test1 ORDER BY f1}} msg] - lappend v $msg -} {0 {11 33}} -do_test select1-4.2 { - set v [catch {execsql {SELECT f1 FROM test1 ORDER BY -f1}} msg] - lappend v $msg -} {0 {33 11}} -do_test select1-4.3 { - set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1,f2)}} msg] - lappend v $msg -} {0 {11 33}} -do_test select1-4.4 { - set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1)}} msg] - lappend v $msg -} {1 {misuse of aggregate function min()}} -do_test select1-4.5 { - catchsql { - SELECT f1 FROM test1 ORDER BY 8.4; - } -} {1 {ORDER BY terms must not be non-integer constants}} -do_test select1-4.6 { - catchsql { - SELECT f1 FROM test1 ORDER BY '8.4'; - } -} {1 {ORDER BY terms must not be non-integer constants}} -do_test select1-4.7.1 { - catchsql { - SELECT f1 FROM test1 ORDER BY 'xyz'; - } -} {1 {ORDER BY terms must not be non-integer constants}} -do_test select1-4.7.2 { - catchsql { - SELECT f1 FROM test1 ORDER BY -8.4; - } -} {1 {ORDER BY terms must not be non-integer constants}} -do_test select1-4.7.3 { - catchsql { - SELECT f1 FROM test1 ORDER BY +8.4; - } -} {1 {ORDER BY terms must not be non-integer constants}} -do_test select1-4.7.4 { - catchsql { - SELECT f1 FROM test1 ORDER BY 4294967296; -- constant larger than 32 bits - } -} {1 {ORDER BY terms must not be non-integer constants}} -do_test select1-4.8 { - execsql { - CREATE TABLE t5(a,b); - INSERT INTO t5 VALUES(1,10); - INSERT INTO t5 VALUES(2,9); - SELECT * FROM t5 ORDER BY 1; - } -} {1 10 2 9} -do_test select1-4.9.1 { - execsql { - SELECT * FROM t5 ORDER BY 2; - } -} {2 9 1 10} -do_test select1-4.9.2 { - execsql { - SELECT * FROM t5 ORDER BY +2; - } -} {2 9 1 10} -do_test select1-4.10.1 { - catchsql { - SELECT * FROM t5 ORDER BY 3; - } -} {1 {ORDER BY column number 3 out of range - should be between 1 and 2}} -do_test select1-4.10.2 { - catchsql { - SELECT * FROM t5 ORDER BY -1; - } -} {1 {ORDER BY column number -1 out of range - should be between 1 and 2}} -do_test select1-4.11 { - execsql { - INSERT INTO t5 VALUES(3,10); - SELECT * FROM t5 ORDER BY 2, 1 DESC; - } -} {2 9 3 10 1 10} -do_test select1-4.12 { - execsql { - SELECT * FROM t5 ORDER BY 1 DESC, b; - } -} {3 10 2 9 1 10} -do_test select1-4.13 { - execsql { - SELECT * FROM t5 ORDER BY b DESC, 1; - } -} {1 10 3 10 2 9} - - -# ORDER BY ignored on an aggregate query -# -do_test select1-5.1 { - set v [catch {execsql {SELECT max(f1) FROM test1 ORDER BY f2}} msg] - lappend v $msg -} {0 33} - -execsql {CREATE TABLE test2(t1 test, t2 text)} -execsql {INSERT INTO test2 VALUES('abc','xyz')} - -# Check for column naming -# -do_test select1-6.1 { - set v [catch {execsql2 {SELECT f1 FROM test1 ORDER BY f2}} msg] - lappend v $msg -} {0 {f1 11 f1 33}} -do_test select1-6.1.1 { - execsql {PRAGMA full_column_names=on} - set v [catch {execsql2 {SELECT f1 FROM test1 ORDER BY f2}} msg] - lappend v $msg -} {0 {test1.f1 11 test1.f1 33}} -do_test select1-6.1.2 { - set v [catch {execsql2 {SELECT f1 as 'f1' FROM test1 ORDER BY f2}} msg] - lappend v $msg -} {0 {f1 11 f1 33}} -do_test select1-6.1.3 { - set v [catch {execsql2 {SELECT * FROM test1 WHERE f1==11}} msg] - lappend v $msg -} {0 {f1 11 f2 22}} -do_test select1-6.1.4 { - set v [catch {execsql2 {SELECT DISTINCT * FROM test1 WHERE f1==11}} msg] - execsql {PRAGMA full_column_names=off} - lappend v $msg -} {0 {f1 11 f2 22}} -do_test select1-6.1.5 { - set v [catch {execsql2 {SELECT * FROM test1 WHERE f1==11}} msg] - lappend v $msg -} {0 {f1 11 f2 22}} -do_test select1-6.1.6 { - set v [catch {execsql2 {SELECT DISTINCT * FROM test1 WHERE f1==11}} msg] - lappend v $msg -} {0 {f1 11 f2 22}} -do_test select1-6.2 { - set v [catch {execsql2 {SELECT f1 as xyzzy FROM test1 ORDER BY f2}} msg] - lappend v $msg -} {0 {xyzzy 11 xyzzy 33}} -do_test select1-6.3 { - set v [catch {execsql2 {SELECT f1 as "xyzzy" FROM test1 ORDER BY f2}} msg] - lappend v $msg -} {0 {xyzzy 11 xyzzy 33}} -do_test select1-6.3.1 { - set v [catch {execsql2 {SELECT f1 as 'xyzzy ' FROM test1 ORDER BY f2}} msg] - lappend v $msg -} {0 {{xyzzy } 11 {xyzzy } 33}} -do_test select1-6.4 { - set v [catch {execsql2 {SELECT f1+F2 as xyzzy FROM test1 ORDER BY f2}} msg] - lappend v $msg -} {0 {xyzzy 33 xyzzy 77}} -do_test select1-6.4a { - set v [catch {execsql2 {SELECT f1+F2 FROM test1 ORDER BY f2}} msg] - lappend v $msg -} {0 {f1+F2 33 f1+F2 77}} -do_test select1-6.5 { - set v [catch {execsql2 {SELECT test1.f1+F2 FROM test1 ORDER BY f2}} msg] - lappend v $msg -} {0 {test1.f1+F2 33 test1.f1+F2 77}} -do_test select1-6.5.1 { - execsql2 {PRAGMA full_column_names=on} - set v [catch {execsql2 {SELECT test1.f1+F2 FROM test1 ORDER BY f2}} msg] - execsql2 {PRAGMA full_column_names=off} - lappend v $msg -} {0 {test1.f1+F2 33 test1.f1+F2 77}} -do_test select1-6.6 { - set v [catch {execsql2 {SELECT test1.f1+F2, t1 FROM test1, test2 - ORDER BY f2}} msg] - lappend v $msg -} {0 {test1.f1+F2 33 t1 abc test1.f1+F2 77 t1 abc}} -do_test select1-6.7 { - set v [catch {execsql2 {SELECT A.f1, t1 FROM test1 as A, test2 - ORDER BY f2}} msg] - lappend v $msg -} {0 {f1 11 t1 abc f1 33 t1 abc}} -do_test select1-6.8 { - set v [catch {execsql2 {SELECT A.f1, f1 FROM test1 as A, test1 as B - ORDER BY f2}} msg] - lappend v $msg -} {1 {ambiguous column name: f1}} -do_test select1-6.8b { - set v [catch {execsql2 {SELECT A.f1, B.f1 FROM test1 as A, test1 as B - ORDER BY f2}} msg] - lappend v $msg -} {1 {ambiguous column name: f2}} -do_test select1-6.8c { - set v [catch {execsql2 {SELECT A.f1, f1 FROM test1 as A, test1 as A - ORDER BY f2}} msg] - lappend v $msg -} {1 {ambiguous column name: A.f1}} -do_test select1-6.9.1 { - set v [catch {execsql {SELECT A.f1, B.f1 FROM test1 as A, test1 as B - ORDER BY A.f1, B.f1}} msg] - lappend v $msg -} {0 {11 11 11 33 33 11 33 33}} -do_test select1-6.9.2 { - set v [catch {execsql2 {SELECT A.f1, B.f1 FROM test1 as A, test1 as B - ORDER BY A.f1, B.f1}} msg] - lappend v $msg -} {0 {f1 11 f1 11 f1 33 f1 33 f1 11 f1 11 f1 33 f1 33}} - -ifcapable compound { -do_test select1-6.10 { - set v [catch {execsql2 { - SELECT f1 FROM test1 UNION SELECT f2 FROM test1 - ORDER BY f2; - }} msg] - lappend v $msg -} {0 {f2 11 f2 22 f2 33 f2 44}} -do_test select1-6.11 { - set v [catch {execsql2 { - SELECT f1 FROM test1 UNION SELECT f2+100 FROM test1 - ORDER BY f2+100; - }} msg] - lappend v $msg -} {0 {f2+100 11 f2+100 33 f2+100 122 f2+100 144}} -} ;#ifcapable compound - -do_test select1-7.1 { - set v [catch {execsql { - SELECT f1 FROM test1 WHERE f2=; - }} msg] - lappend v $msg -} {1 {near ";": syntax error}} -ifcapable compound { -do_test select1-7.2 { - set v [catch {execsql { - SELECT f1 FROM test1 UNION SELECT WHERE; - }} msg] - lappend v $msg -} {1 {near "WHERE": syntax error}} -} ;# ifcapable compound -do_test select1-7.3 { - set v [catch {execsql {SELECT f1 FROM test1 as 'hi', test2 as}} msg] - lappend v $msg -} {1 {near "as": syntax error}} -do_test select1-7.4 { - set v [catch {execsql { - SELECT f1 FROM test1 ORDER BY; - }} msg] - lappend v $msg -} {1 {near ";": syntax error}} -do_test select1-7.5 { - set v [catch {execsql { - SELECT f1 FROM test1 ORDER BY f1 desc, f2 where; - }} msg] - lappend v $msg -} {1 {near "where": syntax error}} -do_test select1-7.6 { - set v [catch {execsql { - SELECT count(f1,f2 FROM test1; - }} msg] - lappend v $msg -} {1 {near "FROM": syntax error}} -do_test select1-7.7 { - set v [catch {execsql { - SELECT count(f1,f2+) FROM test1; - }} msg] - lappend v $msg -} {1 {near ")": syntax error}} -do_test select1-7.8 { - set v [catch {execsql { - SELECT f1 FROM test1 ORDER BY f2, f1+; - }} msg] - lappend v $msg -} {1 {near ";": syntax error}} - -do_test select1-8.1 { - execsql {SELECT f1 FROM test1 WHERE 4.3+2.4 OR 1 ORDER BY f1} -} {11 33} -do_test select1-8.2 { - execsql { - SELECT f1 FROM test1 WHERE ('x' || f1) BETWEEN 'x10' AND 'x20' - ORDER BY f1 - } -} {11} -do_test select1-8.3 { - execsql { - SELECT f1 FROM test1 WHERE 5-3==2 - ORDER BY f1 - } -} {11 33} - -# TODO: This test is failing because f1 is now being loaded off the -# disk as a vdbe integer, not a string. Hence the value of f1/(f1-11) -# changes because of rounding. Disable the test for now. -if 0 { -do_test select1-8.4 { - execsql { - SELECT coalesce(f1/(f1-11),'x'), - coalesce(min(f1/(f1-11),5),'y'), - coalesce(max(f1/(f1-33),6),'z') - FROM test1 ORDER BY f1 - } -} {x y 6 1.5 1.5 z} -} -do_test select1-8.5 { - execsql { - SELECT min(1,2,3), -max(1,2,3) - FROM test1 ORDER BY f1 - } -} {1 -3 1 -3} - - -# Check the behavior when the result set is empty -# -# SQLite v3 always sets r(*). -# -# do_test select1-9.1 { -# catch {unset r} -# set r(*) {} -# db eval {SELECT * FROM test1 WHERE f1<0} r {} -# set r(*) -# } {} -do_test select1-9.2 { - execsql {PRAGMA empty_result_callbacks=on} - catch {unset r} - set r(*) {} - db eval {SELECT * FROM test1 WHERE f1<0} r {} - set r(*) -} {f1 f2} -ifcapable subquery { - do_test select1-9.3 { - set r(*) {} - db eval {SELECT * FROM test1 WHERE f1<(select count(*) from test2)} r {} - set r(*) - } {f1 f2} -} -do_test select1-9.4 { - set r(*) {} - db eval {SELECT * FROM test1 ORDER BY f1} r {} - set r(*) -} {f1 f2} -do_test select1-9.5 { - set r(*) {} - db eval {SELECT * FROM test1 WHERE f1<0 ORDER BY f1} r {} - set r(*) -} {f1 f2} -unset r - -# Check for ORDER BY clauses that refer to an AS name in the column list -# -do_test select1-10.1 { - execsql { - SELECT f1 AS x FROM test1 ORDER BY x - } -} {11 33} -do_test select1-10.2 { - execsql { - SELECT f1 AS x FROM test1 ORDER BY -x - } -} {33 11} -do_test select1-10.3 { - execsql { - SELECT f1-23 AS x FROM test1 ORDER BY abs(x) - } -} {10 -12} -do_test select1-10.4 { - execsql { - SELECT f1-23 AS x FROM test1 ORDER BY -abs(x) - } -} {-12 10} -do_test select1-10.5 { - execsql { - SELECT f1-22 AS x, f2-22 as y FROM test1 - } -} {-11 0 11 22} -do_test select1-10.6 { - execsql { - SELECT f1-22 AS x, f2-22 as y FROM test1 WHERE x>0 AND y<50 - } -} {11 22} - -# Check the ability to specify "TABLE.*" in the result set of a SELECT -# -do_test select1-11.1 { - execsql { - DELETE FROM t3; - DELETE FROM t4; - INSERT INTO t3 VALUES(1,2); - INSERT INTO t4 VALUES(3,4); - SELECT * FROM t3, t4; - } -} {1 2 3 4} -do_test select1-11.2.1 { - execsql { - SELECT * FROM t3, t4; - } -} {1 2 3 4} -do_test select1-11.2.2 { - execsql2 { - SELECT * FROM t3, t4; - } -} {a 3 b 4 a 3 b 4} -do_test select1-11.4.1 { - execsql { - SELECT t3.*, t4.b FROM t3, t4; - } -} {1 2 4} -do_test select1-11.4.2 { - execsql { - SELECT "t3".*, t4.b FROM t3, t4; - } -} {1 2 4} -do_test select1-11.5.1 { - execsql2 { - SELECT t3.*, t4.b FROM t3, t4; - } -} {a 1 b 4 b 4} -do_test select1-11.6 { - execsql2 { - SELECT x.*, y.b FROM t3 AS x, t4 AS y; - } -} {a 1 b 4 b 4} -do_test select1-11.7 { - execsql { - SELECT t3.b, t4.* FROM t3, t4; - } -} {2 3 4} -do_test select1-11.8 { - execsql2 { - SELECT t3.b, t4.* FROM t3, t4; - } -} {b 4 a 3 b 4} -do_test select1-11.9 { - execsql2 { - SELECT x.b, y.* FROM t3 AS x, t4 AS y; - } -} {b 4 a 3 b 4} -do_test select1-11.10 { - catchsql { - SELECT t5.* FROM t3, t4; - } -} {1 {no such table: t5}} -do_test select1-11.11 { - catchsql { - SELECT t3.* FROM t3 AS x, t4; - } -} {1 {no such table: t3}} -ifcapable subquery { - do_test select1-11.12 { - execsql2 { - SELECT t3.* FROM t3, (SELECT max(a), max(b) FROM t4) - } - } {a 1 b 2} - do_test select1-11.13 { - execsql2 { - SELECT t3.* FROM (SELECT max(a), max(b) FROM t4), t3 - } - } {a 1 b 2} - do_test select1-11.14 { - execsql2 { - SELECT * FROM t3, (SELECT max(a), max(b) FROM t4) AS 'tx' - } - } {a 1 b 2 max(a) 3 max(b) 4} - do_test select1-11.15 { - execsql2 { - SELECT y.*, t3.* FROM t3, (SELECT max(a), max(b) FROM t4) AS y - } - } {max(a) 3 max(b) 4 a 1 b 2} -} -do_test select1-11.16 { - execsql2 { - SELECT y.* FROM t3 as y, t4 as z - } -} {a 1 b 2} - -# Tests of SELECT statements without a FROM clause. -# -do_test select1-12.1 { - execsql2 { - SELECT 1+2+3 - } -} {1+2+3 6} -do_test select1-12.2 { - execsql2 { - SELECT 1,'hello',2 - } -} {1 1 'hello' hello 2 2} -do_test select1-12.3 { - execsql2 { - SELECT 1 AS 'a','hello' AS 'b',2 AS 'c' - } -} {a 1 b hello c 2} -do_test select1-12.4 { - execsql { - DELETE FROM t3; - INSERT INTO t3 VALUES(1,2); - } -} {} - -ifcapable compound { -do_test select1-12.5 { - execsql { - SELECT * FROM t3 UNION SELECT 3 AS 'a', 4 ORDER BY a; - } -} {1 2 3 4} - -do_test select1-12.6 { - execsql { - SELECT 3, 4 UNION SELECT * FROM t3; - } -} {1 2 3 4} -} ;# ifcapable compound - -ifcapable subquery { - do_test select1-12.7 { - execsql { - SELECT * FROM t3 WHERE a=(SELECT 1); - } - } {1 2} - do_test select1-12.8 { - execsql { - SELECT * FROM t3 WHERE a=(SELECT 2); - } - } {} -} - -ifcapable {compound && subquery} { - do_test select1-12.9 { - execsql2 { - SELECT x FROM ( - SELECT a,b FROM t3 UNION SELECT a AS 'x', b AS 'y' FROM t4 ORDER BY a,b - ) ORDER BY x; - } - } {x 1 x 3} - do_test select1-12.10 { - execsql2 { - SELECT z.x FROM ( - SELECT a,b FROM t3 UNION SELECT a AS 'x', b AS 'y' FROM t4 ORDER BY a,b - ) AS 'z' ORDER BY x; - } - } {x 1 x 3} -} ;# ifcapable compound - - -finish_test diff --git a/sqlite/test/select2.test b/sqlite/test/select2.test deleted file mode 100644 index 52525a6..0000000 --- a/sqlite/test/select2.test +++ /dev/null @@ -1,184 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the SELECT statement. -# -# $Id: select2.test,v 1.24 2005/01/25 04:27:55 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Create a table with some data -# -execsql {CREATE TABLE tbl1(f1 int, f2 int)} -execsql {BEGIN} -for {set i 0} {$i<=30} {incr i} { - execsql "INSERT INTO tbl1 VALUES([expr {$i%9}],[expr {$i%10}])" -} -execsql {COMMIT} - -# Do a second query inside a first. -# -do_test select2-1.1 { - set sql {SELECT DISTINCT f1 FROM tbl1 ORDER BY f1} - set r {} - catch {unset data} - db eval $sql data { - set f1 $data(f1) - lappend r $f1: - set sql2 "SELECT f2 FROM tbl1 WHERE f1=$f1 ORDER BY f2" - db eval $sql2 d2 { - lappend r $d2(f2) - } - } - set r -} {0: 0 7 8 9 1: 0 1 8 9 2: 0 1 2 9 3: 0 1 2 3 4: 2 3 4 5: 3 4 5 6: 4 5 6 7: 5 6 7 8: 6 7 8} - -do_test select2-1.2 { - set sql {SELECT DISTINCT f1 FROM tbl1 WHERE f1>3 AND f1<5} - set r {} - db eval $sql data { - set f1 $data(f1) - lappend r $f1: - set sql2 "SELECT f2 FROM tbl1 WHERE f1=$f1 ORDER BY f2" - db eval $sql2 d2 { - lappend r $d2(f2) - } - } - set r -} {4: 2 3 4} - -# Create a largish table. Do this twice, once using the TCL cache and once -# without. Compare the performance to make sure things go faster with the -# cache turned on. -# -ifcapable tclvar { - do_test select2-2.0.1 { - set t1 [time { - execsql {CREATE TABLE tbl2(f1 int, f2 int, f3 int); BEGIN;} - for {set i 1} {$i<=30000} {incr i} { - set i2 [expr {$i*2}] - set i3 [expr {$i*3}] - db eval {INSERT INTO tbl2 VALUES($i,$i2,$i3)} - } - execsql {COMMIT} - }] - list - } {} - puts "time with cache: $::t1" -} -catch {execsql {DROP TABLE tbl2}} -do_test select2-2.0.2 { - set t2 [time { - execsql {CREATE TABLE tbl2(f1 int, f2 int, f3 int); BEGIN;} - for {set i 1} {$i<=30000} {incr i} { - set i2 [expr {$i*2}] - set i3 [expr {$i*3}] - execsql "INSERT INTO tbl2 VALUES($i,$i2,$i3)" - } - execsql {COMMIT} - }] - list -} {} -puts "time without cache: $t2" -ifcapable tclvar { - do_test select2-2.0.3 { - expr {[lindex $t1 0]<[lindex $t2 0]} - } 1 -} - -do_test select2-2.1 { - execsql {SELECT count(*) FROM tbl2} -} {30000} -do_test select2-2.2 { - execsql {SELECT count(*) FROM tbl2 WHERE f2>1000} -} {29500} - -do_test select2-3.1 { - execsql {SELECT f1 FROM tbl2 WHERE 1000=f2} -} {500} - -do_test select2-3.2a { - execsql {CREATE INDEX idx1 ON tbl2(f2)} -} {} -do_test select2-3.2b { - execsql {SELECT f1 FROM tbl2 WHERE 1000=f2} -} {500} -do_test select2-3.2c { - execsql {SELECT f1 FROM tbl2 WHERE f2=1000} -} {500} -do_test select2-3.2d { - set sqlite_search_count 0 - execsql {SELECT * FROM tbl2 WHERE 1000=f2} - set sqlite_search_count -} {3} -do_test select2-3.2e { - set sqlite_search_count 0 - execsql {SELECT * FROM tbl2 WHERE f2=1000} - set sqlite_search_count -} {3} - -# Make sure queries run faster with an index than without -# -do_test select2-3.3 { - execsql {DROP INDEX idx1} - set sqlite_search_count 0 - execsql {SELECT f1 FROM tbl2 WHERE f2==2000} - set sqlite_search_count -} {29999} - -# Make sure we can optimize functions in the WHERE clause that -# use fields from two or more different table. (Bug #6) -# -do_test select2-4.1 { - execsql { - CREATE TABLE aa(a); - CREATE TABLE bb(b); - INSERT INTO aa VALUES(1); - INSERT INTO aa VALUES(3); - INSERT INTO bb VALUES(2); - INSERT INTO bb VALUES(4); - SELECT * FROM aa, bb WHERE max(a,b)>2; - } -} {1 4 3 2 3 4} -do_test select2-4.2 { - execsql { - INSERT INTO bb VALUES(0); - SELECT * FROM aa, bb WHERE b; - } -} {1 2 1 4 3 2 3 4} -do_test select2-4.3 { - execsql { - SELECT * FROM aa, bb WHERE NOT b; - } -} {1 0 3 0} -do_test select2-4.4 { - execsql { - SELECT * FROM aa, bb WHERE min(a,b); - } -} {1 2 1 4 3 2 3 4} -do_test select2-4.5 { - execsql { - SELECT * FROM aa, bb WHERE NOT min(a,b); - } -} {1 0 3 0} -do_test select2-4.6 { - execsql { - SELECT * FROM aa, bb WHERE CASE WHEN a=b-1 THEN 1 END; - } -} {1 2 3 4} -do_test select2-4.7 { - execsql { - SELECT * FROM aa, bb WHERE CASE WHEN a=b-1 THEN 0 ELSE 1 END; - } -} {1 4 1 0 3 2 3 0} - -finish_test diff --git a/sqlite/test/select4.test b/sqlite/test/select4.test deleted file mode 100644 index 7ceb564..0000000 --- a/sqlite/test/select4.test +++ /dev/null @@ -1,514 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing UNION, INTERSECT and EXCEPT operators -# in SELECT statements. -# -# $Id: select4.test,v 1.18 2005/01/21 04:25:47 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Most tests in this file depend on compound-select. But there are a couple -# right at the end that test DISTINCT, so we cannot omit the entire file. -# -ifcapable compound { - -# Build some test data -# -execsql { - CREATE TABLE t1(n int, log int); - BEGIN; -} -for {set i 1} {$i<32} {incr i} { - for {set j 0} {pow(2,$j)<$i} {incr j} {} - execsql "INSERT INTO t1 VALUES($i,$j)" -} -execsql { - COMMIT; -} - -do_test select4-1.0 { - execsql {SELECT DISTINCT log FROM t1 ORDER BY log} -} {0 1 2 3 4 5} - -# Union All operator -# -do_test select4-1.1a { - lsort [execsql {SELECT DISTINCT log FROM t1}] -} {0 1 2 3 4 5} -do_test select4-1.1b { - lsort [execsql {SELECT n FROM t1 WHERE log=3}] -} {5 6 7 8} -do_test select4-1.1c { - execsql { - SELECT DISTINCT log FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - } -} {0 1 2 3 4 5 5 6 7 8} -do_test select4-1.1d { - execsql { - CREATE TABLE t2 AS - SELECT DISTINCT log FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - SELECT * FROM t2; - } -} {0 1 2 3 4 5 5 6 7 8} -execsql {DROP TABLE t2} -do_test select4-1.1e { - execsql { - CREATE TABLE t2 AS - SELECT DISTINCT log FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY log DESC; - SELECT * FROM t2; - } -} {8 7 6 5 5 4 3 2 1 0} -execsql {DROP TABLE t2} -do_test select4-1.1f { - execsql { - SELECT DISTINCT log FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=2 - } -} {0 1 2 3 4 5 3 4} -do_test select4-1.1g { - execsql { - CREATE TABLE t2 AS - SELECT DISTINCT log FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=2; - SELECT * FROM t2; - } -} {0 1 2 3 4 5 3 4} -execsql {DROP TABLE t2} -ifcapable subquery { - do_test select4-1.2 { - execsql { - SELECT log FROM t1 WHERE n IN - (SELECT DISTINCT log FROM t1 UNION ALL - SELECT n FROM t1 WHERE log=3) - ORDER BY log; - } - } {0 1 2 2 3 3 3 3} -} -do_test select4-1.3 { - set v [catch {execsql { - SELECT DISTINCT log FROM t1 ORDER BY log - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - }} msg] - lappend v $msg -} {1 {ORDER BY clause should come after UNION ALL not before}} - -# Union operator -# -do_test select4-2.1 { - execsql { - SELECT DISTINCT log FROM t1 - UNION - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - } -} {0 1 2 3 4 5 6 7 8} -ifcapable subquery { - do_test select4-2.2 { - execsql { - SELECT log FROM t1 WHERE n IN - (SELECT DISTINCT log FROM t1 UNION - SELECT n FROM t1 WHERE log=3) - ORDER BY log; - } - } {0 1 2 2 3 3 3 3} -} -do_test select4-2.3 { - set v [catch {execsql { - SELECT DISTINCT log FROM t1 ORDER BY log - UNION - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - }} msg] - lappend v $msg -} {1 {ORDER BY clause should come after UNION not before}} - -# Except operator -# -do_test select4-3.1.1 { - execsql { - SELECT DISTINCT log FROM t1 - EXCEPT - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - } -} {0 1 2 3 4} -do_test select4-3.1.2 { - execsql { - CREATE TABLE t2 AS - SELECT DISTINCT log FROM t1 - EXCEPT - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - SELECT * FROM t2; - } -} {0 1 2 3 4} -execsql {DROP TABLE t2} -do_test select4-3.1.3 { - execsql { - CREATE TABLE t2 AS - SELECT DISTINCT log FROM t1 - EXCEPT - SELECT n FROM t1 WHERE log=3 - ORDER BY log DESC; - SELECT * FROM t2; - } -} {4 3 2 1 0} -execsql {DROP TABLE t2} -ifcapable subquery { - do_test select4-3.2 { - execsql { - SELECT log FROM t1 WHERE n IN - (SELECT DISTINCT log FROM t1 EXCEPT - SELECT n FROM t1 WHERE log=3) - ORDER BY log; - } - } {0 1 2 2} -} -do_test select4-3.3 { - set v [catch {execsql { - SELECT DISTINCT log FROM t1 ORDER BY log - EXCEPT - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - }} msg] - lappend v $msg -} {1 {ORDER BY clause should come after EXCEPT not before}} - -# Intersect operator -# -do_test select4-4.1.1 { - execsql { - SELECT DISTINCT log FROM t1 - INTERSECT - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - } -} {5} - -do_test select4-4.1.2 { - execsql { - SELECT DISTINCT log FROM t1 UNION ALL SELECT 6 - INTERSECT - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - } -} {5 6} -do_test select4-4.1.3 { - execsql { - CREATE TABLE t2 AS - SELECT DISTINCT log FROM t1 UNION ALL SELECT 6 - INTERSECT - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - SELECT * FROM t2; - } -} {5 6} -execsql {DROP TABLE t2} -do_test select4-4.1.4 { - execsql { - CREATE TABLE t2 AS - SELECT DISTINCT log FROM t1 UNION ALL SELECT 6 - INTERSECT - SELECT n FROM t1 WHERE log=3 - ORDER BY log DESC; - SELECT * FROM t2; - } -} {6 5} -execsql {DROP TABLE t2} -ifcapable subquery { - do_test select4-4.2 { - execsql { - SELECT log FROM t1 WHERE n IN - (SELECT DISTINCT log FROM t1 INTERSECT - SELECT n FROM t1 WHERE log=3) - ORDER BY log; - } - } {3} -} -do_test select4-4.3 { - set v [catch {execsql { - SELECT DISTINCT log FROM t1 ORDER BY log - INTERSECT - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - }} msg] - lappend v $msg -} {1 {ORDER BY clause should come after INTERSECT not before}} - -# Various error messages while processing UNION or INTERSECT -# -do_test select4-5.1 { - set v [catch {execsql { - SELECT DISTINCT log FROM t2 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - }} msg] - lappend v $msg -} {1 {no such table: t2}} -do_test select4-5.2 { - set v [catch {execsql { - SELECT DISTINCT log AS "xyzzy" FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY xyzzy; - }} msg] - lappend v $msg -} {0 {0 1 2 3 4 5 5 6 7 8}} -do_test select4-5.2b { - set v [catch {execsql { - SELECT DISTINCT log AS xyzzy FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY 'xyzzy'; - }} msg] - lappend v $msg -} {0 {0 1 2 3 4 5 5 6 7 8}} -do_test select4-5.2c { - set v [catch {execsql { - SELECT DISTINCT log FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY 'xyzzy'; - }} msg] - lappend v $msg -} {1 {ORDER BY term number 1 does not match any result column}} -do_test select4-5.2d { - set v [catch {execsql { - SELECT DISTINCT log FROM t1 - INTERSECT - SELECT n FROM t1 WHERE log=3 - ORDER BY 'xyzzy'; - }} msg] - lappend v $msg -} {1 {ORDER BY term number 1 does not match any result column}} -do_test select4-5.2e { - set v [catch {execsql { - SELECT DISTINCT log FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY n; - }} msg] - lappend v $msg -} {0 {0 1 2 3 4 5 5 6 7 8}} -do_test select4-5.2f { - catchsql { - SELECT DISTINCT log FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - } -} {0 {0 1 2 3 4 5 5 6 7 8}} -do_test select4-5.2g { - catchsql { - SELECT DISTINCT log FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY 1; - } -} {0 {0 1 2 3 4 5 5 6 7 8}} -do_test select4-5.2h { - catchsql { - SELECT DISTINCT log FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY 2; - } -} {1 {ORDER BY position 2 should be between 1 and 1}} -do_test select4-5.2i { - catchsql { - SELECT DISTINCT 1, log FROM t1 - UNION ALL - SELECT 2, n FROM t1 WHERE log=3 - ORDER BY 2, 1; - } -} {0 {1 0 1 1 1 2 1 3 1 4 1 5 2 5 2 6 2 7 2 8}} -do_test select4-5.2j { - catchsql { - SELECT DISTINCT 1, log FROM t1 - UNION ALL - SELECT 2, n FROM t1 WHERE log=3 - ORDER BY 1, 2 DESC; - } -} {0 {1 5 1 4 1 3 1 2 1 1 1 0 2 8 2 7 2 6 2 5}} -do_test select4-5.2k { - catchsql { - SELECT DISTINCT 1, log FROM t1 - UNION ALL - SELECT 2, n FROM t1 WHERE log=3 - ORDER BY n, 1; - } -} {0 {1 0 1 1 1 2 1 3 1 4 1 5 2 5 2 6 2 7 2 8}} -do_test select4-5.3 { - set v [catch {execsql { - SELECT DISTINCT log, n FROM t1 - UNION ALL - SELECT n FROM t1 WHERE log=3 - ORDER BY log; - }} msg] - lappend v $msg -} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}} -do_test select4-5.4 { - set v [catch {execsql { - SELECT log FROM t1 WHERE n=2 - UNION ALL - SELECT log FROM t1 WHERE n=3 - UNION ALL - SELECT log FROM t1 WHERE n=4 - UNION ALL - SELECT log FROM t1 WHERE n=5 - ORDER BY log; - }} msg] - lappend v $msg -} {0 {1 2 2 3}} - -do_test select4-6.1 { - execsql { - SELECT log, count(*) as cnt FROM t1 GROUP BY log - UNION - SELECT log, n FROM t1 WHERE n=7 - ORDER BY cnt, log; - } -} {0 1 1 1 2 2 3 4 3 7 4 8 5 15} -do_test select4-6.2 { - execsql { - SELECT log, count(*) FROM t1 GROUP BY log - UNION - SELECT log, n FROM t1 WHERE n=7 - ORDER BY count(*), log; - } -} {0 1 1 1 2 2 3 4 3 7 4 8 5 15} - -# NULLs are indistinct for the UNION operator. -# Make sure the UNION operator recognizes this -# -do_test select4-6.3 { - execsql { - SELECT NULL UNION SELECT NULL UNION - SELECT 1 UNION SELECT 2 AS 'x' - ORDER BY x; - } -} {{} 1 2} -do_test select4-6.3.1 { - execsql { - SELECT NULL UNION ALL SELECT NULL UNION ALL - SELECT 1 UNION ALL SELECT 2 AS 'x' - ORDER BY x; - } -} {{} {} 1 2} - -# Make sure the DISTINCT keyword treats NULLs as indistinct. -# -ifcapable subquery { - do_test select4-6.4 { - execsql { - SELECT * FROM ( - SELECT NULL, 1 UNION ALL SELECT NULL, 1 - ); - } - } {{} 1 {} 1} - do_test select4-6.5 { - execsql { - SELECT DISTINCT * FROM ( - SELECT NULL, 1 UNION ALL SELECT NULL, 1 - ); - } - } {{} 1} - do_test select4-6.6 { - execsql { - SELECT DISTINCT * FROM ( - SELECT 1,2 UNION ALL SELECT 1,2 - ); - } - } {1 2} -} - -# Test distinctness of NULL in other ways. -# -do_test select4-6.7 { - execsql { - SELECT NULL EXCEPT SELECT NULL - } -} {} - - -# Make sure column names are correct when a compound select appears as -# an expression in the WHERE clause. -# -do_test select4-7.1 { - execsql { - CREATE TABLE t2 AS SELECT log AS 'x', count(*) AS 'y' FROM t1 GROUP BY log; - SELECT * FROM t2 ORDER BY x; - } -} {0 1 1 1 2 2 3 4 4 8 5 15} -ifcapable subquery { - do_test select4-7.2 { - execsql2 { - SELECT * FROM t1 WHERE n IN (SELECT n FROM t1 INTERSECT SELECT x FROM t2) - ORDER BY n - } - } {n 1 log 0 n 2 log 1 n 3 log 2 n 4 log 2 n 5 log 3} - do_test select4-7.3 { - execsql2 { - SELECT * FROM t1 WHERE n IN (SELECT n FROM t1 EXCEPT SELECT x FROM t2) - ORDER BY n LIMIT 2 - } - } {n 6 log 3 n 7 log 3} - do_test select4-7.4 { - execsql2 { - SELECT * FROM t1 WHERE n IN (SELECT n FROM t1 UNION SELECT x FROM t2) - ORDER BY n LIMIT 2 - } - } {n 1 log 0 n 2 log 1} -} ;# ifcapable subquery - -} ;# ifcapable compound - -# Make sure DISTINCT works appropriately on TEXT and NUMERIC columns. -do_test select4-8.1 { - execsql { - BEGIN; - CREATE TABLE t3(a text, b float, c text); - INSERT INTO t3 VALUES(1, 1.1, '1.1'); - INSERT INTO t3 VALUES(2, 1.10, '1.10'); - INSERT INTO t3 VALUES(3, 1.10, '1.1'); - INSERT INTO t3 VALUES(4, 1.1, '1.10'); - INSERT INTO t3 VALUES(5, 1.2, '1.2'); - INSERT INTO t3 VALUES(6, 1.3, '1.3'); - COMMIT; - } - execsql { - SELECT DISTINCT b FROM t3 ORDER BY c; - } -} {1.1 1.2 1.3} -do_test select4-8.2 { - execsql { - SELECT DISTINCT c FROM t3 ORDER BY c; - } -} {1.1 1.10 1.2 1.3} - - -finish_test diff --git a/sqlite/test/select5.test b/sqlite/test/select5.test deleted file mode 100644 index fb739f2..0000000 --- a/sqlite/test/select5.test +++ /dev/null @@ -1,156 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing aggregate functions and the -# GROUP BY and HAVING clauses of SELECT statements. -# -# $Id: select5.test,v 1.9 2005/01/26 03:58:36 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Build some test data -# -execsql { - CREATE TABLE t1(x int, y int); - BEGIN; -} -for {set i 1} {$i<32} {incr i} { - for {set j 0} {pow(2,$j)<$i} {incr j} {} - execsql "INSERT INTO t1 VALUES([expr {32-$i}],[expr {10-$j}])" -} -execsql { - COMMIT -} - -do_test select5-1.0 { - execsql {SELECT DISTINCT y FROM t1 ORDER BY y} -} {5 6 7 8 9 10} - -# Sort by an aggregate function. -# -do_test select5-1.1 { - execsql {SELECT y, count(*) FROM t1 GROUP BY y ORDER BY y} -} {5 15 6 8 7 4 8 2 9 1 10 1} -do_test select5-1.2 { - execsql {SELECT y, count(*) FROM t1 GROUP BY y ORDER BY count(*), y} -} {9 1 10 1 8 2 7 4 6 8 5 15} -do_test select5-1.3 { - execsql {SELECT count(*), y FROM t1 GROUP BY y ORDER BY count(*), y} -} {1 9 1 10 2 8 4 7 8 6 15 5} - -# Some error messages associated with aggregates and GROUP BY -# -do_test select5-2.1 { - set v [catch {execsql { - SELECT y, count(*) FROM t1 GROUP BY z ORDER BY y - }} msg] - lappend v $msg -} {1 {no such column: z}} -do_test select5-2.2 { - set v [catch {execsql { - SELECT y, count(*) FROM t1 GROUP BY z(y) ORDER BY y - }} msg] - lappend v $msg -} {1 {no such function: z}} -do_test select5-2.3 { - set v [catch {execsql { - SELECT y, count(*) FROM t1 GROUP BY y HAVING count(*)<3 ORDER BY y - }} msg] - lappend v $msg -} {0 {8 2 9 1 10 1}} -do_test select5-2.4 { - set v [catch {execsql { - SELECT y, count(*) FROM t1 GROUP BY y HAVING z(y)<3 ORDER BY y - }} msg] - lappend v $msg -} {1 {no such function: z}} -do_test select5-2.5 { - set v [catch {execsql { - SELECT y, count(*) FROM t1 GROUP BY y HAVING count(*)100 - } -} {{}} -do_test select5-4.2 { - execsql { - SELECT count(x) FROM t1 WHERE x>100 - } -} {0} -do_test select5-4.3 { - execsql { - SELECT min(x) FROM t1 WHERE x>100 - } -} {{}} -do_test select5-4.4 { - execsql { - SELECT max(x) FROM t1 WHERE x>100 - } -} {{}} -do_test select5-4.5 { - execsql { - SELECT sum(x) FROM t1 WHERE x>100 - } -} {0.0} - -# Some tests for queries with a GROUP BY clause but no aggregate functions. -# -# Note: The query in test case 5-5.5 are not legal SQL. So if the -# implementation changes in the future and it returns different results, -# this is not such a big deal. -# -do_test select5-5.1 { - execsql { - CREATE TABLE t2(a, b, c); - INSERT INTO t2 VALUES(1, 2, 3); - INSERT INTO t2 VALUES(1, 4, 5); - INSERT INTO t2 VALUES(6, 4, 7); - CREATE INDEX t2_idx ON t2(a); - } -} {} -do_test select5-5.2 { - execsql { - SELECT a FROM t2 GROUP BY a; - } -} {1 6} -do_test select5-5.3 { - execsql { - SELECT a FROM t2 WHERE a>2 GROUP BY a; - } -} {6} -do_test select5-5.4 { - execsql { - SELECT a, b FROM t2 GROUP BY a, b; - } -} {1 2 1 4 6 4} -do_test select5-5.5 { - execsql { - SELECT a, b FROM t2 GROUP BY a; - } -} {1 2 6 4} - -finish_test - diff --git a/sqlite/test/select6.test b/sqlite/test/select6.test deleted file mode 100644 index acb9fb9..0000000 --- a/sqlite/test/select6.test +++ /dev/null @@ -1,457 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing SELECT statements that contain -# subqueries in their FROM clause. -# -# $Id: select6.test,v 1.17 2005/01/29 08:32:46 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Omit this whole file if the library is build without subquery support. -ifcapable !subquery { - finish_test - return -} - -do_test select6-1.0 { - execsql { - BEGIN; - CREATE TABLE t1(x, y); - INSERT INTO t1 VALUES(1,1); - INSERT INTO t1 VALUES(2,2); - INSERT INTO t1 VALUES(3,2); - INSERT INTO t1 VALUES(4,3); - INSERT INTO t1 VALUES(5,3); - INSERT INTO t1 VALUES(6,3); - INSERT INTO t1 VALUES(7,3); - INSERT INTO t1 VALUES(8,4); - INSERT INTO t1 VALUES(9,4); - INSERT INTO t1 VALUES(10,4); - INSERT INTO t1 VALUES(11,4); - INSERT INTO t1 VALUES(12,4); - INSERT INTO t1 VALUES(13,4); - INSERT INTO t1 VALUES(14,4); - INSERT INTO t1 VALUES(15,4); - INSERT INTO t1 VALUES(16,5); - INSERT INTO t1 VALUES(17,5); - INSERT INTO t1 VALUES(18,5); - INSERT INTO t1 VALUES(19,5); - INSERT INTO t1 VALUES(20,5); - COMMIT; - SELECT DISTINCT y FROM t1 ORDER BY y; - } -} {1 2 3 4 5} - -do_test select6-1.1 { - execsql2 {SELECT * FROM (SELECT x, y FROM t1 WHERE x<2)} -} {x 1 y 1} -do_test select6-1.2 { - execsql {SELECT count(*) FROM (SELECT y FROM t1)} -} {20} -do_test select6-1.3 { - execsql {SELECT count(*) FROM (SELECT DISTINCT y FROM t1)} -} {5} -do_test select6-1.4 { - execsql {SELECT count(*) FROM (SELECT DISTINCT * FROM (SELECT y FROM t1))} -} {5} -do_test select6-1.5 { - execsql {SELECT count(*) FROM (SELECT * FROM (SELECT DISTINCT y FROM t1))} -} {5} - -do_test select6-1.6 { - execsql { - SELECT * - FROM (SELECT count(*),y FROM t1 GROUP BY y) AS a, - (SELECT max(x),y FROM t1 GROUP BY y) as b - WHERE a.y=b.y ORDER BY a.y - } -} {1 1 1 1 2 2 3 2 4 3 7 3 8 4 15 4 5 5 20 5} -do_test select6-1.7 { - execsql { - SELECT a.y, a.[count(*)], [max(x)], [count(*)] - FROM (SELECT count(*),y FROM t1 GROUP BY y) AS a, - (SELECT max(x),y FROM t1 GROUP BY y) as b - WHERE a.y=b.y ORDER BY a.y - } -} {1 1 1 1 2 2 3 2 3 4 7 4 4 8 15 8 5 5 20 5} -do_test select6-1.8 { - execsql { - SELECT q, p, r - FROM (SELECT count(*) as p , y as q FROM t1 GROUP BY y) AS a, - (SELECT max(x) as r, y as s FROM t1 GROUP BY y) as b - WHERE q=s ORDER BY s - } -} {1 1 1 2 2 3 3 4 7 4 8 15 5 5 20} -do_test select6-1.9 { - execsql { - SELECT q, p, r, b.[min(x)+y] - FROM (SELECT count(*) as p , y as q FROM t1 GROUP BY y) AS a, - (SELECT max(x) as r, y as s, min(x)+y FROM t1 GROUP BY y) as b - WHERE q=s ORDER BY s - } -} {1 1 1 2 2 2 3 4 3 4 7 7 4 8 15 12 5 5 20 21} - -do_test select6-2.0 { - execsql { - CREATE TABLE t2(a INTEGER PRIMARY KEY, b); - INSERT INTO t2 SELECT * FROM t1; - SELECT DISTINCT b FROM t2 ORDER BY b; - } -} {1 2 3 4 5} -do_test select6-2.1 { - execsql2 {SELECT * FROM (SELECT a, b FROM t2 WHERE a<2)} -} {a 1 b 1} -do_test select6-2.2 { - execsql {SELECT count(*) FROM (SELECT b FROM t2)} -} {20} -do_test select6-2.3 { - execsql {SELECT count(*) FROM (SELECT DISTINCT b FROM t2)} -} {5} -do_test select6-2.4 { - execsql {SELECT count(*) FROM (SELECT DISTINCT * FROM (SELECT b FROM t2))} -} {5} -do_test select6-2.5 { - execsql {SELECT count(*) FROM (SELECT * FROM (SELECT DISTINCT b FROM t2))} -} {5} - -do_test select6-2.6 { - execsql { - SELECT * - FROM (SELECT count(*),b FROM t2 GROUP BY b) AS a, - (SELECT max(a),b FROM t2 GROUP BY b) as b - WHERE a.b=b.b ORDER BY a.b - } -} {1 1 1 1 2 2 3 2 4 3 7 3 8 4 15 4 5 5 20 5} -do_test select6-2.7 { - execsql { - SELECT a.b, a.[count(*)], [max(a)], [count(*)] - FROM (SELECT count(*),b FROM t2 GROUP BY b) AS a, - (SELECT max(a),b FROM t2 GROUP BY b) as b - WHERE a.b=b.b ORDER BY a.b - } -} {1 1 1 1 2 2 3 2 3 4 7 4 4 8 15 8 5 5 20 5} -do_test select6-2.8 { - execsql { - SELECT q, p, r - FROM (SELECT count(*) as p , b as q FROM t2 GROUP BY b) AS a, - (SELECT max(a) as r, b as s FROM t2 GROUP BY b) as b - WHERE q=s ORDER BY s - } -} {1 1 1 2 2 3 3 4 7 4 8 15 5 5 20} -do_test select6-2.9 { - execsql { - SELECT a.q, a.p, b.r - FROM (SELECT count(*) as p , b as q FROM t2 GROUP BY q) AS a, - (SELECT max(a) as r, b as s FROM t2 GROUP BY s) as b - WHERE a.q=b.s ORDER BY a.q - } -} {1 1 1 2 2 3 3 4 7 4 8 15 5 5 20} - -do_test select6-3.1 { - execsql2 { - SELECT * FROM (SELECT * FROM (SELECT * FROM t1 WHERE x=3)); - } -} {x 3 y 2} -do_test select6-3.2 { - execsql { - SELECT * FROM - (SELECT a.q, a.p, b.r - FROM (SELECT count(*) as p , b as q FROM t2 GROUP BY q) AS a, - (SELECT max(a) as r, b as s FROM t2 GROUP BY s) as b - WHERE a.q=b.s ORDER BY a.q) - ORDER BY "a.q" - } -} {1 1 1 2 2 3 3 4 7 4 8 15 5 5 20} -do_test select6-3.3 { - execsql { - SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1) - } -} {10.5 3.7 14.2} -do_test select6-3.4 { - execsql { - SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1 WHERE y=4) - } -} {11.5 4.0 15.5} -do_test select6-3.5 { - execsql { - SELECT x,y,x+y FROM (SELECT avg(a) as 'x', avg(b) as 'y' FROM t2 WHERE a=4) - } -} {4.0 3.0 7.0} -do_test select6-3.6 { - execsql { - SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1) - WHERE a>10 - } -} {10.5 3.7 14.2} -do_test select6-3.7 { - execsql { - SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1) - WHERE a<10 - } -} {} -do_test select6-3.8 { - execsql { - SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1 WHERE y=4) - WHERE a>10 - } -} {11.5 4.0 15.5} -do_test select6-3.9 { - execsql { - SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1 WHERE y=4) - WHERE a<10 - } -} {} -do_test select6-3.10 { - execsql { - SELECT a,b,a+b FROM (SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b) - ORDER BY a - } -} {1.0 1 2.0 2.5 2 4.5 5.5 3 8.5 11.5 4 15.5 18.0 5 23.0} -do_test select6-3.11 { - execsql { - SELECT a,b,a+b FROM - (SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b) - WHERE b<4 ORDER BY a - } -} {1.0 1 2.0 2.5 2 4.5 5.5 3 8.5} -do_test select6-3.12 { - execsql { - SELECT a,b,a+b FROM - (SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b HAVING a>1) - WHERE b<4 ORDER BY a - } -} {2.5 2 4.5 5.5 3 8.5} -do_test select6-3.13 { - execsql { - SELECT a,b,a+b FROM - (SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b HAVING a>1) - ORDER BY a - } -} {2.5 2 4.5 5.5 3 8.5 11.5 4 15.5 18.0 5 23.0} -do_test select6-3.14 { - execsql { - SELECT [count(*)],y FROM (SELECT count(*), y FROM t1 GROUP BY y) - ORDER BY [count(*)] - } -} {1 1 2 2 4 3 5 5 8 4} -do_test select6-3.15 { - execsql { - SELECT [count(*)],y FROM (SELECT count(*), y FROM t1 GROUP BY y) - ORDER BY y - } -} {1 1 2 2 4 3 8 4 5 5} - -do_test select6-4.1 { - execsql { - SELECT a,b,c FROM - (SELECT x AS 'a', y AS 'b', x+y AS 'c' FROM t1 WHERE y=4) - WHERE a<10 ORDER BY a; - } -} {8 4 12 9 4 13} -do_test select6-4.2 { - execsql { - SELECT y FROM (SELECT DISTINCT y FROM t1) WHERE y<5 ORDER BY y - } -} {1 2 3 4} -do_test select6-4.3 { - execsql { - SELECT DISTINCT y FROM (SELECT y FROM t1) WHERE y<5 ORDER BY y - } -} {1 2 3 4} -do_test select6-4.4 { - execsql { - SELECT avg(y) FROM (SELECT DISTINCT y FROM t1) WHERE y<5 ORDER BY y - } -} {2.5} -do_test select6-4.5 { - execsql { - SELECT avg(y) FROM (SELECT DISTINCT y FROM t1 WHERE y<5) ORDER BY y - } -} {2.5} - -do_test select6-5.1 { - execsql { - SELECT a,x,b FROM - (SELECT x+3 AS 'a', x FROM t1 WHERE y=3) AS 'p', - (SELECT x AS 'b' FROM t1 WHERE y=4) AS 'q' - WHERE a=b - ORDER BY a - } -} {8 5 8 9 6 9 10 7 10} -do_test select6-5.2 { - execsql { - SELECT a,x,b FROM - (SELECT x+3 AS 'a', x FROM t1 WHERE y=3), - (SELECT x AS 'b' FROM t1 WHERE y=4) - WHERE a=b - ORDER BY a - } -} {8 5 8 9 6 9 10 7 10} - -# Tests of compound sub-selects -# -ifcapable compound { -do_test select5-6.1 { - execsql { - DELETE FROM t1 WHERE x>4; - SELECT * FROM t1 - } -} {1 1 2 2 3 2 4 3} -do_test select6-6.2 { - execsql { - SELECT * FROM ( - SELECT x AS 'a' FROM t1 UNION ALL SELECT x+10 AS 'a' FROM t1 - ) ORDER BY a; - } -} {1 2 3 4 11 12 13 14} -do_test select6-6.3 { - execsql { - SELECT * FROM ( - SELECT x AS 'a' FROM t1 UNION ALL SELECT x+1 AS 'a' FROM t1 - ) ORDER BY a; - } -} {1 2 2 3 3 4 4 5} -do_test select6-6.4 { - execsql { - SELECT * FROM ( - SELECT x AS 'a' FROM t1 UNION SELECT x+1 AS 'a' FROM t1 - ) ORDER BY a; - } -} {1 2 3 4 5} -do_test select6-6.5 { - execsql { - SELECT * FROM ( - SELECT x AS 'a' FROM t1 INTERSECT SELECT x+1 AS 'a' FROM t1 - ) ORDER BY a; - } -} {2 3 4} -do_test select6-6.6 { - execsql { - SELECT * FROM ( - SELECT x AS 'a' FROM t1 EXCEPT SELECT x*2 AS 'a' FROM t1 - ) ORDER BY a; - } -} {1 3} -} ;# ifcapable compound - -# Subselects with no FROM clause -# -do_test select6-7.1 { - execsql { - SELECT * FROM (SELECT 1) - } -} {1} -do_test select6-7.2 { - execsql { - SELECT c,b,a,* FROM (SELECT 1 AS 'a', 2 AS 'b', 'abc' AS 'c') - } -} {abc 2 1 1 2 abc} -do_test select6-7.3 { - execsql { - SELECT c,b,a,* FROM (SELECT 1 AS 'a', 2 AS 'b', 'abc' AS 'c' WHERE 0) - } -} {} -do_test select6-7.4 { - execsql2 { - SELECT c,b,a,* FROM (SELECT 1 AS 'a', 2 AS 'b', 'abc' AS 'c' WHERE 1) - } -} {c abc b 2 a 1 a 1 b 2 c abc} - -# The remaining tests in this file depend on the EXPLAIN keyword. -# Skip these tests if EXPLAIN is disabled in the current build. -# -ifcapable {!explain} { - finish_test - return -} - -# The following procedure compiles the SQL given as an argument and returns -# TRUE if that SQL uses any transient tables and returns FALSE if no -# transient tables are used. This is used to make sure that the -# sqliteFlattenSubquery() routine in select.c is doing its job. -# -proc is_flat {sql} { - return [expr 0>[lsearch [execsql "EXPLAIN $sql"] OpenTemp]] -} - -# Check that the flattener works correctly for deeply nested subqueries -# involving joins. -# -do_test select6-8.1 { - execsql { - BEGIN; - CREATE TABLE t3(p,q); - INSERT INTO t3 VALUES(1,11); - INSERT INTO t3 VALUES(2,22); - CREATE TABLE t4(q,r); - INSERT INTO t4 VALUES(11,111); - INSERT INTO t4 VALUES(22,222); - COMMIT; - SELECT * FROM t3 NATURAL JOIN t4; - } -} {1 11 111 2 22 222} -do_test select6-8.2 { - execsql { - SELECT y, p, q, r FROM - (SELECT t1.y AS y, t2.b AS b FROM t1, t2 WHERE t1.x=t2.a) AS m, - (SELECT t3.p AS p, t3.q AS q, t4.r AS r FROM t3 NATURAL JOIN t4) as n - WHERE y=p - } -} {1 1 11 111 2 2 22 222 2 2 22 222} -# If view support is omitted from the build, then so is the query -# "flattener". So omit this test and test select6-8.6 in that case. -ifcapable view { -do_test select6-8.3 { - is_flat { - SELECT y, p, q, r FROM - (SELECT t1.y AS y, t2.b AS b FROM t1, t2 WHERE t1.x=t2.a) AS m, - (SELECT t3.p AS p, t3.q AS q, t4.r AS r FROM t3 NATURAL JOIN t4) as n - WHERE y=p - } -} {1} -} ;# ifcapable view -do_test select6-8.4 { - execsql { - SELECT DISTINCT y, p, q, r FROM - (SELECT t1.y AS y, t2.b AS b FROM t1, t2 WHERE t1.x=t2.a) AS m, - (SELECT t3.p AS p, t3.q AS q, t4.r AS r FROM t3 NATURAL JOIN t4) as n - WHERE y=p - } -} {1 1 11 111 2 2 22 222} -do_test select6-8.5 { - execsql { - SELECT * FROM - (SELECT y, p, q, r FROM - (SELECT t1.y AS y, t2.b AS b FROM t1, t2 WHERE t1.x=t2.a) AS m, - (SELECT t3.p AS p, t3.q AS q, t4.r AS r FROM t3 NATURAL JOIN t4) as n - WHERE y=p) AS e, - (SELECT r AS z FROM t4 WHERE q=11) AS f - WHERE e.r=f.z - } -} {1 1 11 111 111} -ifcapable view { -do_test select6-8.6 { - is_flat { - SELECT * FROM - (SELECT y, p, q, r FROM - (SELECT t1.y AS y, t2.b AS b FROM t1, t2 WHERE t1.x=t2.a) AS m, - (SELECT t3.p AS p, t3.q AS q, t4.r AS r FROM t3 NATURAL JOIN t4) as n - WHERE y=p) AS e, - (SELECT r AS z FROM t4 WHERE q=11) AS f - WHERE e.r=f.z - } -} {1} -} ;# ifcapable view - - -finish_test diff --git a/sqlite/test/select7.test b/sqlite/test/select7.test deleted file mode 100644 index 4f45366..0000000 --- a/sqlite/test/select7.test +++ /dev/null @@ -1,73 +0,0 @@ -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this file is testing compute SELECT statements and nested -# views. -# -# $Id: select7.test,v 1.6 2005/01/26 03:58:37 danielk1977 Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -ifcapable compound { - -# A 3-way INTERSECT. Ticket #875 -do_test select7-1.1 { - execsql { - create temp table t1(x); - insert into t1 values('amx'); - insert into t1 values('anx'); - insert into t1 values('amy'); - insert into t1 values('bmy'); - select * from t1 where x like 'a__' - intersect select * from t1 where x like '_m_' - intersect select * from t1 where x like '__x'; - } -} {amx} - - -# Nested views do not handle * properly. Ticket #826. -# -ifcapable view { -do_test select7-2.1 { - execsql { - CREATE TABLE x(id integer primary key, a TEXT NULL); - INSERT INTO x (a) VALUES ('first'); - CREATE TABLE tempx(id integer primary key, a TEXT NULL); - INSERT INTO tempx (a) VALUES ('t-first'); - CREATE VIEW tv1 AS SELECT x.id, tx.id FROM x JOIN tempx tx ON tx.id=x.id; - CREATE VIEW tv1b AS SELECT x.id, tx.id FROM x JOIN tempx tx on tx.id=x.id; - CREATE VIEW tv2 AS SELECT * FROM tv1 UNION SELECT * FROM tv1b; - SELECT * FROM tv2; - } -} {1 1} -} ;# ifcapable view - -} ;# ifcapable compound - -# Do not allow GROUP BY without an aggregate. Ticket #1039. -# -# Change: force any query with a GROUP BY clause to be processed as -# an aggregate query, whether it contains aggregates or not. -# -ifcapable subquery { - # do_test select7-3.1 { - # catchsql { - # SELECT * FROM (SELECT * FROM sqlite_master) GROUP BY name - # } - # } {1 {GROUP BY may only be used on aggregate queries}} - do_test select7-3.1 { - catchsql { - SELECT * FROM (SELECT * FROM sqlite_master) GROUP BY name - } - } [list 0 [execsql {SELECT * FROM sqlite_master ORDER BY name}]] -} -finish_test - diff --git a/sqlite/test/sort.test b/sqlite/test/sort.test deleted file mode 100644 index 6d527c3..0000000 --- a/sqlite/test/sort.test +++ /dev/null @@ -1,435 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the CREATE TABLE statement. -# -# $Id: sort.test,v 1.19 2005/02/02 01:10:45 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Create a bunch of data to sort against -# -do_test sort-1.0 { - execsql { - CREATE TABLE t1( - n int, - v varchar(10), - log int, - roman varchar(10), - flt real - ); - INSERT INTO t1 VALUES(1,'one',0,'I',3.141592653); - INSERT INTO t1 VALUES(2,'two',1,'II',2.15); - INSERT INTO t1 VALUES(3,'three',1,'III',4221.0); - INSERT INTO t1 VALUES(4,'four',2,'IV',-0.0013442); - INSERT INTO t1 VALUES(5,'five',2,'V',-11); - INSERT INTO t1 VALUES(6,'six',2,'VI',0.123); - INSERT INTO t1 VALUES(7,'seven',2,'VII',123.0); - INSERT INTO t1 VALUES(8,'eight',3,'VIII',-1.6); - } - execsql {SELECT count(*) FROM t1} -} {8} - -do_test sort-1.1 { - execsql {SELECT n FROM t1 ORDER BY n} -} {1 2 3 4 5 6 7 8} -do_test sort-1.1.1 { - execsql {SELECT n FROM t1 ORDER BY n ASC} -} {1 2 3 4 5 6 7 8} -do_test sort-1.1.1 { - execsql {SELECT ALL n FROM t1 ORDER BY n ASC} -} {1 2 3 4 5 6 7 8} -do_test sort-1.2 { - execsql {SELECT n FROM t1 ORDER BY n DESC} -} {8 7 6 5 4 3 2 1} -do_test sort-1.3a { - execsql {SELECT v FROM t1 ORDER BY v} -} {eight five four one seven six three two} -do_test sort-1.3b { - execsql {SELECT n FROM t1 ORDER BY v} -} {8 5 4 1 7 6 3 2} -do_test sort-1.4 { - execsql {SELECT n FROM t1 ORDER BY v DESC} -} {2 3 6 7 1 4 5 8} -do_test sort-1.5 { - execsql {SELECT flt FROM t1 ORDER BY flt} -} {-11 -1.6 -0.0013442 0.123 2.15 3.141592653 123.0 4221.0} -do_test sort-1.6 { - execsql {SELECT flt FROM t1 ORDER BY flt DESC} -} {4221.0 123.0 3.141592653 2.15 0.123 -0.0013442 -1.6 -11} -do_test sort-1.7 { - execsql {SELECT roman FROM t1 ORDER BY roman} -} {I II III IV V VI VII VIII} -do_test sort-1.8 { - execsql {SELECT n FROM t1 ORDER BY log, flt} -} {1 2 3 5 4 6 7 8} -do_test sort-1.8.1 { - execsql {SELECT n FROM t1 ORDER BY log asc, flt} -} {1 2 3 5 4 6 7 8} -do_test sort-1.8.2 { - execsql {SELECT n FROM t1 ORDER BY log, flt ASC} -} {1 2 3 5 4 6 7 8} -do_test sort-1.8.3 { - execsql {SELECT n FROM t1 ORDER BY log ASC, flt asc} -} {1 2 3 5 4 6 7 8} -do_test sort-1.9 { - execsql {SELECT n FROM t1 ORDER BY log, flt DESC} -} {1 3 2 7 6 4 5 8} -do_test sort-1.9.1 { - execsql {SELECT n FROM t1 ORDER BY log ASC, flt DESC} -} {1 3 2 7 6 4 5 8} -do_test sort-1.10 { - execsql {SELECT n FROM t1 ORDER BY log DESC, flt} -} {8 5 4 6 7 2 3 1} -do_test sort-1.11 { - execsql {SELECT n FROM t1 ORDER BY log DESC, flt DESC} -} {8 7 6 4 5 3 2 1} - -# These tests are designed to reach some hard-to-reach places -# inside the string comparison routines. -# -# (Later) The sorting behavior changed in 2.7.0. But we will -# keep these tests. You can never have too many test cases! -# -do_test sort-2.1.1 { - execsql { - UPDATE t1 SET v='x' || -flt; - UPDATE t1 SET v='x-2b' where v=='x-0.123'; - SELECT v FROM t1 ORDER BY v; - } -} {x-123 x-2.15 x-2b x-3.141592653 x-4221 x0.0013442 x1.6 x11} -do_test sort-2.1.2 { - execsql { - SELECT v FROM t1 ORDER BY substr(v,2,999); - } -} {x-123 x-2.15 x-2b x-3.141592653 x-4221 x0.0013442 x1.6 x11} -do_test sort-2.1.3 { - execsql { - SELECT v FROM t1 ORDER BY substr(v,2,999)+0.0; - } -} {x-4221 x-123 x-3.141592653 x-2.15 x-2b x0.0013442 x1.6 x11} -do_test sort-2.1.4 { - execsql { - SELECT v FROM t1 ORDER BY substr(v,2,999) DESC; - } -} {x11 x1.6 x0.0013442 x-4221 x-3.141592653 x-2b x-2.15 x-123} -do_test sort-2.1.5 { - execsql { - SELECT v FROM t1 ORDER BY substr(v,2,999)+0.0 DESC; - } -} {x11 x1.6 x0.0013442 x-2b x-2.15 x-3.141592653 x-123 x-4221} - -# This is a bug fix for 2.2.4. -# Strings are normally mapped to upper-case for a caseless comparison. -# But this can cause problems for characters in between 'Z' and 'a'. -# -do_test sort-3.1 { - execsql { - CREATE TABLE t2(a,b); - INSERT INTO t2 VALUES('AGLIENTU',1); - INSERT INTO t2 VALUES('AGLIE`',2); - INSERT INTO t2 VALUES('AGNA',3); - SELECT a, b FROM t2 ORDER BY a; - } -} {AGLIENTU 1 AGLIE` 2 AGNA 3} -do_test sort-3.2 { - execsql { - SELECT a, b FROM t2 ORDER BY a DESC; - } -} {AGNA 3 AGLIE` 2 AGLIENTU 1} -do_test sort-3.3 { - execsql { - DELETE FROM t2; - INSERT INTO t2 VALUES('aglientu',1); - INSERT INTO t2 VALUES('aglie`',2); - INSERT INTO t2 VALUES('agna',3); - SELECT a, b FROM t2 ORDER BY a; - } -} {aglie` 2 aglientu 1 agna 3} -do_test sort-3.4 { - execsql { - SELECT a, b FROM t2 ORDER BY a DESC; - } -} {agna 3 aglientu 1 aglie` 2} - -# Version 2.7.0 testing. -# -do_test sort-4.1 { - execsql { - INSERT INTO t1 VALUES(9,'x2.7',3,'IX',4.0e5); - INSERT INTO t1 VALUES(10,'x5.0e10',3,'X',-4.0e5); - INSERT INTO t1 VALUES(11,'x-4.0e9',3,'XI',4.1e4); - INSERT INTO t1 VALUES(12,'x01234567890123456789',3,'XII',-4.2e3); - SELECT n FROM t1 ORDER BY n; - } -} {1 2 3 4 5 6 7 8 9 10 11 12} -do_test sort-4.2 { - execsql { - SELECT n||'' FROM t1 ORDER BY 1; - } -} {1 10 11 12 2 3 4 5 6 7 8 9} -do_test sort-4.3 { - execsql { - SELECT n+0 FROM t1 ORDER BY 1; - } -} {1 2 3 4 5 6 7 8 9 10 11 12} -do_test sort-4.4 { - execsql { - SELECT n||'' FROM t1 ORDER BY 1 DESC; - } -} {9 8 7 6 5 4 3 2 12 11 10 1} -do_test sort-4.5 { - execsql { - SELECT n+0 FROM t1 ORDER BY 1 DESC; - } -} {12 11 10 9 8 7 6 5 4 3 2 1} -do_test sort-4.6 { - execsql { - SELECT v FROM t1 ORDER BY 1; - } -} {x-123 x-2.15 x-2b x-3.141592653 x-4.0e9 x-4221 x0.0013442 x01234567890123456789 x1.6 x11 x2.7 x5.0e10} -do_test sort-4.7 { - execsql { - SELECT v FROM t1 ORDER BY 1 DESC; - } -} {x5.0e10 x2.7 x11 x1.6 x01234567890123456789 x0.0013442 x-4221 x-4.0e9 x-3.141592653 x-2b x-2.15 x-123} -do_test sort-4.8 { - execsql { - SELECT substr(v,2,99) FROM t1 ORDER BY 1; - } -} {-123 -2.15 -2b -3.141592653 -4.0e9 -4221 0.0013442 01234567890123456789 1.6 11 2.7 5.0e10} -#do_test sort-4.9 { -# execsql { -# SELECT substr(v,2,99)+0.0 FROM t1 ORDER BY 1; -# } -#} {-4000000000 -4221 -123 -3.141592653 -2.15 -2 0.0013442 1.6 2.7 11 50000000000 1.23456789012346e+18} - -do_test sort-5.1 { - execsql { - create table t3(a,b); - insert into t3 values(5,NULL); - insert into t3 values(6,NULL); - insert into t3 values(3,NULL); - insert into t3 values(4,'cd'); - insert into t3 values(1,'ab'); - insert into t3 values(2,NULL); - select a from t3 order by b, a; - } -} {2 3 5 6 1 4} -do_test sort-5.2 { - execsql { - select a from t3 order by b, a desc; - } -} {6 5 3 2 1 4} -do_test sort-5.3 { - execsql { - select a from t3 order by b desc, a; - } -} {4 1 2 3 5 6} -do_test sort-5.4 { - execsql { - select a from t3 order by b desc, a desc; - } -} {4 1 6 5 3 2} - -do_test sort-6.1 { - execsql { - create index i3 on t3(b,a); - select a from t3 order by b, a; - } -} {2 3 5 6 1 4} -do_test sort-6.2 { - execsql { - select a from t3 order by b, a desc; - } -} {6 5 3 2 1 4} -do_test sort-6.3 { - execsql { - select a from t3 order by b desc, a; - } -} {4 1 2 3 5 6} -do_test sort-6.4 { - execsql { - select a from t3 order by b desc, a desc; - } -} {4 1 6 5 3 2} - -do_test sort-7.1 { - execsql { - CREATE TABLE t4( - a INTEGER, - b VARCHAR(30) - ); - INSERT INTO t4 VALUES(1,1); - INSERT INTO t4 VALUES(2,2); - INSERT INTO t4 VALUES(11,11); - INSERT INTO t4 VALUES(12,12); - SELECT a FROM t4 ORDER BY 1; - } -} {1 2 11 12} -do_test sort-7.2 { - execsql { - SELECT b FROM t4 ORDER BY 1 - } -} {1 11 12 2} - -# Omit tests sort-7.3 to sort-7.8 if view support was disabled at -# compilatation time. -ifcapable view { -do_test sort-7.3 { - execsql { - CREATE VIEW v4 AS SELECT * FROM t4; - SELECT a FROM v4 ORDER BY 1; - } -} {1 2 11 12} -do_test sort-7.4 { - execsql { - SELECT b FROM v4 ORDER BY 1; - } -} {1 11 12 2} - -ifcapable compound { -do_test sort-7.5 { - execsql { - SELECT a FROM t4 UNION SELECT a FROM v4 ORDER BY 1; - } -} {1 2 11 12} -do_test sort-7.6 { - execsql { - SELECT b FROM t4 UNION SELECT a FROM v4 ORDER BY 1; - } -} {1 2 11 12 1 11 12 2} ;# text from t4.b and numeric from v4.a -do_test sort-7.7 { - execsql { - SELECT a FROM t4 UNION SELECT b FROM v4 ORDER BY 1; - } -} {1 2 11 12 1 11 12 2} ;# numeric from t4.a and text from v4.b -do_test sort-7.8 { - execsql { - SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1; - } -} {1 11 12 2} -} ;# ifcapable compound -} ;# ifcapable view - -#### Version 3 works differently here: -#do_test sort-7.9 { -# execsql { -# SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE numeric; -# } -#} {1 2 11 12} -#do_test sort-7.10 { -# execsql { -# SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE integer; -# } -#} {1 2 11 12} -#do_test sort-7.11 { -# execsql { -# SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE text; -# } -#} {1 11 12 2} -#do_test sort-7.12 { -# execsql { -# SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE blob; -# } -#} {1 11 12 2} -#do_test sort-7.13 { -# execsql { -# SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE clob; -# } -#} {1 11 12 2} -#do_test sort-7.14 { -# execsql { -# SELECT b FROM t4 UNION SELECT b FROM v4 ORDER BY 1 COLLATE varchar; -# } -#} {1 11 12 2} - -# Ticket #297 -# -do_test sort-8.1 { - execsql { - CREATE TABLE t5(a real, b text); - INSERT INTO t5 VALUES(100,'A1'); - INSERT INTO t5 VALUES(100.0,'A2'); - SELECT * FROM t5 ORDER BY a, b; - } -} {100 A1 100.0 A2} - - -ifcapable {bloblit} { -# BLOBs should sort after TEXT -# -do_test sort-9.1 { - execsql { - CREATE TABLE t6(x, y); - INSERT INTO t6 VALUES(1,1); - INSERT INTO t6 VALUES(2,'1'); - INSERT INTO t6 VALUES(3,x'31'); - INSERT INTO t6 VALUES(4,NULL); - SELECT x FROM t6 ORDER BY y; - } -} {4 1 2 3} -do_test sort-9.2 { - execsql { - SELECT x FROM t6 ORDER BY y DESC; - } -} {3 2 1 4} -do_test sort-9.3 { - execsql { - SELECT x FROM t6 WHERE y<1 - } -} {} -do_test sort-9.4 { - execsql { - SELECT x FROM t6 WHERE y<'1' - } -} {1} -do_test sort-9.5 { - execsql { - SELECT x FROM t6 WHERE y1 - } -} {2 3} -do_test sort-9.7 { - execsql { - SELECT x FROM t6 WHERE y>'1' - } -} {3} -} ;# endif bloblit - -# Ticket #1092 - ORDER BY on rowid fields. -do_test sort-10.1 { - execsql { - CREATE TABLE t7(c INTEGER PRIMARY KEY); - INSERT INTO t7 VALUES(1); - INSERT INTO t7 VALUES(2); - INSERT INTO t7 VALUES(3); - INSERT INTO t7 VALUES(4); - } -} {} -do_test sort-10.2 { - execsql { - SELECT c FROM t7 WHERE c<=3 ORDER BY c DESC; - } -} {3 2 1} -do_test sort-10.3 { - execsql { - SELECT c FROM t7 WHERE c<3 ORDER BY c DESC; - } -} {2 1} - -finish_test - diff --git a/sqlite/test/subquery.test b/sqlite/test/subquery.test deleted file mode 100644 index 137968b..0000000 --- a/sqlite/test/subquery.test +++ /dev/null @@ -1,333 +0,0 @@ -# 2005 January 19 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing correlated subqueries -# -# $Id: subquery.test,v 1.7 2005/02/12 08:59:59 danielk1977 Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -ifcapable !subquery { - finish_test - return -} - -do_test subquery-1.1 { - execsql { - BEGIN; - CREATE TABLE t1(a,b); - INSERT INTO t1 VALUES(1,2); - INSERT INTO t1 VALUES(3,4); - INSERT INTO t1 VALUES(5,6); - INSERT INTO t1 VALUES(7,8); - CREATE TABLE t2(x,y); - INSERT INTO t2 VALUES(1,1); - INSERT INTO t2 VALUES(3,9); - INSERT INTO t2 VALUES(5,25); - INSERT INTO t2 VALUES(7,49); - COMMIT; - } - execsql { - SELECT a, (SELECT y FROM t2 WHERE x=a) FROM t1 WHERE b<8 - } -} {1 1 3 9 5 25} -do_test subquery-1.2 { - execsql { - UPDATE t1 SET b=b+(SELECT y FROM t2 WHERE x=a); - SELECT * FROM t1; - } -} {1 3 3 13 5 31 7 57} - -do_test subquery-1.3 { - execsql { - SELECT b FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE y=a) - } -} {3} -do_test subquery-1.4 { - execsql { - SELECT b FROM t1 WHERE NOT EXISTS(SELECT * FROM t2 WHERE y=a) - } -} {13 31 57} - -# Simple tests to make sure correlated subqueries in WHERE clauses -# are used by the query optimizer correctly. -do_test subquery-1.5 { - execsql { - SELECT a, x FROM t1, t2 WHERE t1.a = (SELECT x); - } -} {1 1 3 3 5 5 7 7} -do_test subquery-1.6 { - execsql { - CREATE INDEX i1 ON t1(a); - SELECT a, x FROM t1, t2 WHERE t1.a = (SELECT x); - } -} {1 1 3 3 5 5 7 7} -do_test subquery-1.7 { - execsql { - SELECT a, x FROM t2, t1 WHERE t1.a = (SELECT x); - } -} {1 1 3 3 5 5 7 7} - -# Try an aggregate in both the subquery and the parent query. -do_test subquery-1.8 { - execsql { - SELECT count(*) FROM t1 WHERE a > (SELECT count(*) FROM t2); - } -} {2} - -# Test a correlated subquery disables the "only open the index" optimization. -do_test subquery-1.9.1 { - execsql { - SELECT (y*2)>b FROM t1, t2 WHERE a=x; - } -} {0 1 1 1} -do_test subquery-1.9.2 { - execsql { - SELECT a FROM t1 WHERE (SELECT (y*2)>b FROM t2 WHERE a=x); - } -} {3 5 7} - -# Test that the flattening optimization works with subquery expressions. -do_test subquery-1.10.1 { - execsql { - SELECT (SELECT a), b FROM t1; - } -} {1 3 3 13 5 31 7 57} -do_test subquery-1.10.2 { - execsql { - SELECT * FROM (SELECT (SELECT a), b FROM t1); - } -} {1 3 3 13 5 31 7 57} -do_test subquery-1.10.3 { - execsql { - SELECT * FROM (SELECT (SELECT sum(a) FROM t1)); - } -} {16.0} -do_test subquery-1.10.4 { - execsql { - CREATE TABLE t5 (val int, period text PRIMARY KEY); - INSERT INTO t5 VALUES(5, '2001-3'); - INSERT INTO t5 VALUES(10, '2001-4'); - INSERT INTO t5 VALUES(15, '2002-1'); - INSERT INTO t5 VALUES(5, '2002-2'); - INSERT INTO t5 VALUES(10, '2002-3'); - INSERT INTO t5 VALUES(15, '2002-4'); - INSERT INTO t5 VALUES(10, '2003-1'); - INSERT INTO t5 VALUES(5, '2003-2'); - INSERT INTO t5 VALUES(25, '2003-3'); - INSERT INTO t5 VALUES(5, '2003-4'); - - SELECT "a.period", vsum - FROM (SELECT - a.period, - (select sum(val) from t5 where period between a.period and '2002-4') vsum - FROM t5 a where a.period between '2002-1' and '2002-4') - WHERE vsum < 45 ; - } -} {2002-2 30.0 2002-3 25.0 2002-4 15.0} -do_test subquery-1.10.5 { - execsql { - DROP TABLE t5; - } -} {} - - - -#------------------------------------------------------------------ -# The following test cases - subquery-2.* - are not logically -# organized. They're here largely because they were failing during -# one stage of development of sub-queries. -# -do_test subquery-2.1 { - execsql { - SELECT (SELECT 10); - } -} {10} -do_test subquery-2.2.1 { - execsql { - CREATE TABLE t3(a PRIMARY KEY, b); - INSERT INTO t3 VALUES(1, 2); - INSERT INTO t3 VALUES(3, 1); - } -} {} -do_test subquery-2.2.2 { - execsql { - SELECT * FROM t3 WHERE a IN (SELECT b FROM t3); - } -} {1 2} -do_test subquery-2.2.3 { - execsql { - DROP TABLE t3; - } -} {} -do_test subquery-2.3.1 { - execsql { - CREATE TABLE t3(a TEXT); - INSERT INTO t3 VALUES('10'); - } -} {} -do_test subquery-2.3.2 { - execsql { - SELECT a IN (10.0, 20) FROM t3; - } -} {0} -do_test subquery-2.3.3 { - execsql { - DROP TABLE t3; - } -} {} -do_test subquery-2.4.1 { - execsql { - CREATE TABLE t3(a TEXT); - INSERT INTO t3 VALUES('XX'); - } -} {} -do_test subquery-2.4.2 { - execsql { - SELECT count(*) FROM t3 WHERE a IN (SELECT 'XX') - } -} {1} -do_test subquery-2.4.3 { - execsql { - DROP TABLE t3; - } -} {} -do_test subquery-2.5.1 { - execsql { - CREATE TABLE t3(a INTEGER); - INSERT INTO t3 VALUES(10); - - CREATE TABLE t4(x TEXT); - INSERT INTO t4 VALUES('10.0'); - } -} {} -do_test subquery-2.5.2 { - execsql { - SELECT * FROM t4 WHERE x IN (SELECT a FROM t3); - } -} {10.0} -do_test subquery-2.5.3 { - execsql { - CREATE INDEX t4i ON t4(x); - SELECT * FROM t4 WHERE x IN (SELECT a FROM t3); - } -} {10.0} -do_test subquery-2.5.4 { - execsql { - DROP TABLE t3; - DROP TABLE t4; - } -} {} - -#------------------------------------------------------------------ -# The following test cases - subquery-3.* - test tickets that -# were raised during development of correlated subqueries. -# - -# Ticket 1083 -ifcapable view { - do_test subquery-3.1 { - catchsql { DROP TABLE t1; } - catchsql { DROP TABLE t2; } - execsql { - CREATE TABLE t1(a,b); - INSERT INTO t1 VALUES(1,2); - CREATE VIEW v1 AS SELECT b FROM t1 WHERE a>0; - CREATE TABLE t2(p,q); - INSERT INTO t2 VALUES(2,9); - SELECT * FROM v1 WHERE EXISTS(SELECT * FROM t2 WHERE p=v1.b); - } - } {2} -} - -# Ticket 1084 -do_test subquery-3.2 { - catchsql { - CREATE TABLE t1(a,b); - INSERT INTO t1 VALUES(1,2); - } - execsql { - SELECT (SELECT t1.a) FROM t1; - } -} {1} - -# Test Cases subquery-3.3.* test correlated subqueries where the -# parent query is an aggregate query. Ticket #1105 is an example -# of such a query. -# -do_test subquery-3.3.1 { - execsql { - SELECT a, (SELECT b) FROM t1 GROUP BY a; - } -} {1 2} -do_test subquery-3.3.2 { - catchsql {DROP TABLE t2} - execsql { - CREATE TABLE t2(c, d); - INSERT INTO t2 VALUES(1, 'one'); - INSERT INTO t2 VALUES(2, 'two'); - SELECT a, (SELECT d FROM t2 WHERE a=c) FROM t1 GROUP BY a; - } -} {1 one} -do_test subquery-3.3.3 { - execsql { - INSERT INTO t1 VALUES(2, 4); - SELECT max(a), (SELECT d FROM t2 WHERE a=c) FROM t1; - } -} {2 two} -do_test subquery-3.3.4 { - execsql { - SELECT a, (SELECT (SELECT d FROM t2 WHERE a=c)) FROM t1 GROUP BY a; - } -} {1 one 2 two} -do_test subquery-3.3.5 { - execsql { - SELECT a, (SELECT count(*) FROM t2 WHERE a=c) FROM t1; - } -} {1 1 2 1} - -#------------------------------------------------------------------ -# These tests - subquery-4.* - use the TCL statement cache to try -# and expose bugs to do with re-using statements that have been -# passed to sqlite3_reset(). -# -# One problem was that VDBE memory cells were not being initialised -# to NULL on the second and subsequent executions. -# -do_test subquery-4.1.1 { - execsql { - SELECT (SELECT a FROM t1); - } -} {1} -do_test subquery-4.2 { - execsql { - DELETE FROM t1; - SELECT (SELECT a FROM t1); - } -} {{}} -do_test subquery-4.2.1 { - execsql { - CREATE TABLE t3(a PRIMARY KEY); - INSERT INTO t3 VALUES(10); - } - execsql {INSERT INTO t3 VALUES((SELECT max(a) FROM t3)+1)} -} {} -do_test subquery-4.2.2 { - execsql {INSERT INTO t3 VALUES((SELECT max(a) FROM t3)+1)} -} {} - - - -finish_test - - diff --git a/sqlite/test/subselect.test b/sqlite/test/subselect.test deleted file mode 100644 index 58f68b1..0000000 --- a/sqlite/test/subselect.test +++ /dev/null @@ -1,178 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing SELECT statements that are part of -# expressions. -# -# $Id: subselect.test,v 1.12 2005/01/21 03:12:16 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Omit this whole file if the library is build without subquery support. -ifcapable !subquery { - finish_test - return -} - -# Basic sanity checking. Try a simple subselect. -# -do_test subselect-1.1 { - execsql { - CREATE TABLE t1(a int, b int); - INSERT INTO t1 VALUES(1,2); - INSERT INTO t1 VALUES(3,4); - INSERT INTO t1 VALUES(5,6); - } - execsql {SELECT * FROM t1 WHERE a = (SELECT count(*) FROM t1)} -} {3 4} - -# Try a select with more than one result column. -# -do_test subselect-1.2 { - set v [catch {execsql {SELECT * FROM t1 WHERE a = (SELECT * FROM t1)}} msg] - lappend v $msg -} {1 {only a single result allowed for a SELECT that is part of an expression}} - -# A subselect without an aggregate. -# -do_test subselect-1.3a { - execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=2)} -} {2} -do_test subselect-1.3b { - execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=4)} -} {4} -do_test subselect-1.3c { - execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=6)} -} {6} -do_test subselect-1.3c { - execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=8)} -} {} - -# What if the subselect doesn't return any value. We should get -# NULL as the result. Check it out. -# -do_test subselect-1.4 { - execsql {SELECT b from t1 where a = coalesce((SELECT a FROM t1 WHERE b=5),1)} -} {2} - -# Try multiple subselects within a single expression. -# -do_test subselect-1.5 { - execsql { - CREATE TABLE t2(x int, y int); - INSERT INTO t2 VALUES(1,2); - INSERT INTO t2 VALUES(2,4); - INSERT INTO t2 VALUES(3,8); - INSERT INTO t2 VALUES(4,16); - } - execsql { - SELECT y from t2 - WHERE x = (SELECT sum(b) FROM t1 where a notnull) - (SELECT sum(a) FROM t1) - } -} {8} - -# Try something useful. Delete every entry from t2 where the -# x value is less than half of the maximum. -# -do_test subselect-1.6 { - execsql {DELETE FROM t2 WHERE x < 0.5*(SELECT max(x) FROM t2)} - execsql {SELECT x FROM t2 ORDER BY x} -} {2 3 4} - -# Make sure sorting works for SELECTs there used as a scalar expression. -# -do_test subselect-2.1 { - execsql { - SELECT (SELECT a FROM t1 ORDER BY a), (SELECT a FROM t1 ORDER BY a DESC) - } -} {1 5} -do_test subselect-2.2 { - execsql { - SELECT 1 IN (SELECT a FROM t1 ORDER BY a); - } -} {1} -do_test subselect-2.3 { - execsql { - SELECT 2 IN (SELECT a FROM t1 ORDER BY a DESC); - } -} {0} - -# Verify that the ORDER BY clause is honored in a subquery. -# -ifcapable compound { -do_test subselect-3.1 { - execsql { - CREATE TABLE t3(x int); - INSERT INTO t3 SELECT a FROM t1 UNION ALL SELECT b FROM t1; - SELECT * FROM t3 ORDER BY x; - } -} {1 2 3 4 5 6} -} ;# ifcapable compound -ifcapable !compound { -do_test subselect-3.1 { - execsql { - CREATE TABLE t3(x int); - INSERT INTO t3 SELECT a FROM t1; - INSERT INTO t3 SELECT b FROM t1; - SELECT * FROM t3 ORDER BY x; - } -} {1 2 3 4 5 6} -} ;# ifcapable !compound - -do_test subselect-3.2 { - execsql { - SELECT sum(x) FROM (SELECT x FROM t3 ORDER BY x LIMIT 2); - } -} {3.0} -do_test subselect-3.3 { - execsql { - SELECT sum(x) FROM (SELECT x FROM t3 ORDER BY x DESC LIMIT 2); - } -} {11.0} -do_test subselect-3.4 { - execsql { - SELECT (SELECT x FROM t3 ORDER BY x); - } -} {1} -do_test subselect-3.5 { - execsql { - SELECT (SELECT x FROM t3 ORDER BY x DESC); - } -} {6} -do_test subselect-3.6 { - execsql { - SELECT (SELECT x FROM t3 ORDER BY x LIMIT 1); - } -} {1} -do_test subselect-3.7 { - execsql { - SELECT (SELECT x FROM t3 ORDER BY x DESC LIMIT 1); - } -} {6} -do_test subselect-3.8 { - execsql { - SELECT (SELECT x FROM t3 ORDER BY x LIMIT 1 OFFSET 2); - } -} {3} -do_test subselect-3.9 { - execsql { - SELECT (SELECT x FROM t3 ORDER BY x DESC LIMIT 1 OFFSET 2); - } -} {4} -do_test subselect-3.10 { - execsql { - SELECT x FROM t3 WHERE x IN - (SELECT x FROM t3 ORDER BY x DESC LIMIT 1 OFFSET 2); - } -} {4} - -finish_test diff --git a/sqlite/test/table.test b/sqlite/test/table.test deleted file mode 100644 index a527964..0000000 --- a/sqlite/test/table.test +++ /dev/null @@ -1,660 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the CREATE TABLE statement. -# -# $Id: table.test,v 1.38 2005/01/24 10:26:00 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Create a basic table and verify it is added to sqlite_master -# -do_test table-1.1 { - execsql { - CREATE TABLE test1 ( - one varchar(10), - two text - ) - } - execsql { - SELECT sql FROM sqlite_master WHERE type!='meta' - } -} {{CREATE TABLE test1 ( - one varchar(10), - two text - )}} - - -# Verify the other fields of the sqlite_master file. -# -do_test table-1.3 { - execsql {SELECT name, tbl_name, type FROM sqlite_master WHERE type!='meta'} -} {test1 test1 table} - -# Close and reopen the database. Verify that everything is -# still the same. -# -do_test table-1.4 { - db close - sqlite3 db test.db - execsql {SELECT name, tbl_name, type from sqlite_master WHERE type!='meta'} -} {test1 test1 table} - -# Drop the database and make sure it disappears. -# -do_test table-1.5 { - execsql {DROP TABLE test1} - execsql {SELECT * FROM sqlite_master WHERE type!='meta'} -} {} - -# Close and reopen the database. Verify that the table is -# still gone. -# -do_test table-1.6 { - db close - sqlite3 db test.db - execsql {SELECT name FROM sqlite_master WHERE type!='meta'} -} {} - -# Repeat the above steps, but this time quote the table name. -# -do_test table-1.10 { - execsql {CREATE TABLE "create" (f1 int)} - execsql {SELECT name FROM sqlite_master WHERE type!='meta'} -} {create} -do_test table-1.11 { - execsql {DROP TABLE "create"} - execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'} -} {} -do_test table-1.12 { - execsql {CREATE TABLE test1("f1 ho" int)} - execsql {SELECT name as "X" FROM sqlite_master WHERE type!='meta'} -} {test1} -do_test table-1.13 { - execsql {DROP TABLE "TEST1"} - execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'} -} {} - - - -# Verify that we cannot make two tables with the same name -# -do_test table-2.1 { - execsql {CREATE TABLE TEST2(one text)} - set v [catch {execsql {CREATE TABLE test2(two text)}} msg] - lappend v $msg -} {1 {table test2 already exists}} -do_test table-2.1b { - set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg] - lappend v $msg -} {1 {object name reserved for internal use: sqlite_master}} -do_test table-2.1c { - db close - sqlite3 db test.db - set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg] - lappend v $msg -} {1 {object name reserved for internal use: sqlite_master}} -do_test table-2.1d { - execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'} -} {} - -# Verify that we cannot make a table with the same name as an index -# -do_test table-2.2a { - execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)} - set v [catch {execsql {CREATE TABLE test3(two text)}} msg] - lappend v $msg -} {1 {there is already an index named test3}} -do_test table-2.2b { - db close - sqlite3 db test.db - set v [catch {execsql {CREATE TABLE test3(two text)}} msg] - lappend v $msg -} {1 {there is already an index named test3}} -do_test table-2.2c { - execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name} -} {test2 test3} -do_test table-2.2d { - execsql {DROP INDEX test3} - set v [catch {execsql {CREATE TABLE test3(two text)}} msg] - lappend v $msg -} {0 {}} -do_test table-2.2e { - execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name} -} {test2 test3} -do_test table-2.2f { - execsql {DROP TABLE test2; DROP TABLE test3} - execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name} -} {} - -# Create a table with many field names -# -set big_table \ -{CREATE TABLE big( - f1 varchar(20), - f2 char(10), - f3 varchar(30) primary key, - f4 text, - f5 text, - f6 text, - f7 text, - f8 text, - f9 text, - f10 text, - f11 text, - f12 text, - f13 text, - f14 text, - f15 text, - f16 text, - f17 text, - f18 text, - f19 text, - f20 text -)} -do_test table-3.1 { - execsql $big_table - execsql {SELECT sql FROM sqlite_master WHERE type=='table'} -} \{$big_table\} -do_test table-3.2 { - set v [catch {execsql {CREATE TABLE BIG(xyz foo)}} msg] - lappend v $msg -} {1 {table BIG already exists}} -do_test table-3.3 { - set v [catch {execsql {CREATE TABLE biG(xyz foo)}} msg] - lappend v $msg -} {1 {table biG already exists}} -do_test table-3.4 { - set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg] - lappend v $msg -} {1 {table bIg already exists}} -do_test table-3.5 { - db close - sqlite3 db test.db - set v [catch {execsql {CREATE TABLE Big(xyz foo)}} msg] - lappend v $msg -} {1 {table Big already exists}} -do_test table-3.6 { - execsql {DROP TABLE big} - execsql {SELECT name FROM sqlite_master WHERE type!='meta'} -} {} - -# Try creating large numbers of tables -# -set r {} -for {set i 1} {$i<=100} {incr i} { - lappend r [format test%03d $i] -} -do_test table-4.1 { - for {set i 1} {$i<=100} {incr i} { - set sql "CREATE TABLE [format test%03d $i] (" - for {set k 1} {$k<$i} {incr k} { - append sql "field$k text," - } - append sql "last_field text)" - execsql $sql - } - execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name} -} $r -do_test table-4.1b { - db close - sqlite3 db test.db - execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name} -} $r - -# Drop the even numbered tables -# -set r {} -for {set i 1} {$i<=100} {incr i 2} { - lappend r [format test%03d $i] -} -do_test table-4.2 { - for {set i 2} {$i<=100} {incr i 2} { - # if {$i==38} {execsql {pragma vdbe_trace=on}} - set sql "DROP TABLE [format TEST%03d $i]" - execsql $sql - } - execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name} -} $r -#exit - -# Drop the odd number tables -# -do_test table-4.3 { - for {set i 1} {$i<=100} {incr i 2} { - set sql "DROP TABLE [format test%03d $i]" - execsql $sql - } - execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name} -} {} - -# Try to drop a table that does not exist -# -do_test table-5.1 { - set v [catch {execsql {DROP TABLE test009}} msg] - lappend v $msg -} {1 {no such table: test009}} - -# Try to drop sqlite_master -# -do_test table-5.2 { - set v [catch {execsql {DROP TABLE sqlite_master}} msg] - lappend v $msg -} {1 {table sqlite_master may not be dropped}} - -# Make sure an EXPLAIN does not really create a new table -# -do_test table-5.3 { - ifcapable {explain} { - execsql {EXPLAIN CREATE TABLE test1(f1 int)} - } - execsql {SELECT name FROM sqlite_master WHERE type!='meta'} -} {} - -# Make sure an EXPLAIN does not really drop an existing table -# -do_test table-5.4 { - execsql {CREATE TABLE test1(f1 int)} - ifcapable {explain} { - execsql {EXPLAIN DROP TABLE test1} - } - execsql {SELECT name FROM sqlite_master WHERE type!='meta'} -} {test1} - -# Create a table with a goofy name -# -#do_test table-6.1 { -# execsql {CREATE TABLE 'Spaces In This Name!'(x int)} -# execsql {INSERT INTO 'spaces in this name!' VALUES(1)} -# set list [glob -nocomplain testdb/spaces*.tbl] -#} {testdb/spaces+in+this+name+.tbl} - -# Try using keywords as table names or column names. -# -do_test table-7.1 { - set v [catch {execsql { - CREATE TABLE weird( - desc text, - asc text, - key int, - [14_vac] boolean, - fuzzy_dog_12 varchar(10), - begin blob, - end clob - ) - }} msg] - lappend v $msg -} {0 {}} -do_test table-7.2 { - execsql { - INSERT INTO weird VALUES('a','b',9,0,'xyz','hi','y''all'); - SELECT * FROM weird; - } -} {a b 9 0 xyz hi y'all} -do_test table-7.3 { - execsql2 { - SELECT * FROM weird; - } -} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all} - -# Try out the CREATE TABLE AS syntax -# -do_test table-8.1 { - execsql2 { - CREATE TABLE t2 AS SELECT * FROM weird; - SELECT * FROM t2; - } -} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all} -do_test table-8.1.1 { - execsql { - SELECT sql FROM sqlite_master WHERE name='t2'; - } -} {{CREATE TABLE t2( - "desc" text, - "asc" text, - "key" int, - "14_vac" boolean, - fuzzy_dog_12 varchar(10), - "begin" blob, - "end" clob -)}} -do_test table-8.2 { - execsql { - CREATE TABLE "t3""xyz"(a,b,c); - INSERT INTO [t3"xyz] VALUES(1,2,3); - SELECT * FROM [t3"xyz]; - } -} {1 2 3} -do_test table-8.3 { - execsql2 { - CREATE TABLE [t4"abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3"xyz]; - SELECT * FROM [t4"abc]; - } -} {cnt 1 max(b+c) 5} - -# Update for v3: The declaration type of anything except a column is now a -# NULL pointer, so the created table has no column types. (Changed result -# from {{CREATE TABLE 't4"abc'(cnt NUMERIC,"max(b+c)" NUMERIC)}}). -do_test table-8.3.1 { - execsql { - SELECT sql FROM sqlite_master WHERE name='t4"abc' - } -} {{CREATE TABLE "t4""abc"(cnt,"max(b+c)")}} -do_test table-8.4 { - execsql2 { - CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3"xyz]; - SELECT * FROM t5; - } -} {y'all 1} -do_test table-8.5 { - db close - sqlite3 db test.db - execsql2 { - SELECT * FROM [t4"abc]; - } -} {cnt 1 max(b+c) 5} -do_test table-8.6 { - execsql2 { - SELECT * FROM t2; - } -} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all} -do_test table-8.7 { - catchsql { - SELECT * FROM t5; - } -} {1 {no such table: t5}} -do_test table-8.8 { - catchsql { - CREATE TABLE t5 AS SELECT * FROM no_such_table; - } -} {1 {no such table: no_such_table}} - -# Make sure we cannot have duplicate column names within a table. -# -do_test table-9.1 { - catchsql { - CREATE TABLE t6(a,b,a); - } -} {1 {duplicate column name: a}} - -# Check the foreign key syntax. -# -ifcapable {foreignkey} { -do_test table-10.1 { - catchsql { - CREATE TABLE t6(a REFERENCES t4(a) NOT NULL); - INSERT INTO t6 VALUES(NULL); - } -} {1 {t6.a may not be NULL}} -do_test table-10.2 { - catchsql { - DROP TABLE t6; - CREATE TABLE t6(a REFERENCES t4(a) MATCH PARTIAL); - } -} {0 {}} -do_test table-10.3 { - catchsql { - DROP TABLE t6; - CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON DELETE SET NULL NOT NULL); - } -} {0 {}} -do_test table-10.4 { - catchsql { - DROP TABLE t6; - CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON UPDATE SET DEFAULT DEFAULT 1); - } -} {0 {}} -do_test table-10.5 { - catchsql { - DROP TABLE t6; - CREATE TABLE t6(a NOT NULL NOT DEFERRABLE INITIALLY IMMEDIATE); - } -} {0 {}} -do_test table-10.6 { - catchsql { - DROP TABLE t6; - CREATE TABLE t6(a NOT NULL DEFERRABLE INITIALLY DEFERRED); - } -} {0 {}} -do_test table-10.7 { - catchsql { - DROP TABLE t6; - CREATE TABLE t6(a, - FOREIGN KEY (a) REFERENCES t4(b) DEFERRABLE INITIALLY DEFERRED - ); - } -} {0 {}} -do_test table-10.8 { - catchsql { - DROP TABLE t6; - CREATE TABLE t6(a,b,c, - FOREIGN KEY (b,c) REFERENCES t4(x,y) MATCH PARTIAL - ON UPDATE SET NULL ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED - ); - } -} {0 {}} -do_test table-10.9 { - catchsql { - DROP TABLE t6; - CREATE TABLE t6(a,b,c, - FOREIGN KEY (b,c) REFERENCES t4(x) - ); - } -} {1 {number of columns in foreign key does not match the number of columns in the referenced table}} -do_test table-10.10 { - catchsql {DROP TABLE t6} - catchsql { - CREATE TABLE t6(a,b,c, - FOREIGN KEY (b,c) REFERENCES t4(x,y,z) - ); - } -} {1 {number of columns in foreign key does not match the number of columns in the referenced table}} -do_test table-10.11 { - catchsql {DROP TABLE t6} - catchsql { - CREATE TABLE t6(a,b, c REFERENCES t4(x,y)); - } -} {1 {foreign key on c should reference only one column of table t4}} -do_test table-10.12 { - catchsql {DROP TABLE t6} - catchsql { - CREATE TABLE t6(a,b,c, - FOREIGN KEY (b,x) REFERENCES t4(x,y) - ); - } -} {1 {unknown column "x" in foreign key definition}} -do_test table-10.13 { - catchsql {DROP TABLE t6} - catchsql { - CREATE TABLE t6(a,b,c, - FOREIGN KEY (x,b) REFERENCES t4(x,y) - ); - } -} {1 {unknown column "x" in foreign key definition}} -} ;# endif foreignkey - -# Test for the "typeof" function. More tests for the -# typeof() function are found in bind.test and types.test. -# -do_test table-11.1 { - execsql { - CREATE TABLE t7( - a integer primary key, - b number(5,10), - c character varying (8), - d VARCHAR(9), - e clob, - f BLOB, - g Text, - h - ); - INSERT INTO t7(a) VALUES(1); - SELECT typeof(a), typeof(b), typeof(c), typeof(d), - typeof(e), typeof(f), typeof(g), typeof(h) - FROM t7 LIMIT 1; - } -} {integer null null null null null null null} -do_test table-11.2 { - execsql { - SELECT typeof(a+b), typeof(a||b), typeof(c+d), typeof(c||d) - FROM t7 LIMIT 1; - } -} {null null null null} - -# Test that when creating a table using CREATE TABLE AS, column types are -# assigned correctly for (SELECT ...) and 'x AS y' expressions. -do_test table-12.1 { - ifcapable subquery { - execsql { - CREATE TABLE t8 AS SELECT b, h, a as i, (SELECT f FROM t7) as j FROM t7; - } - } else { - execsql { - CREATE TABLE t8 AS SELECT b, h, a as i, f as j FROM t7; - } - } -} {} -do_test table-12.2 { - execsql { - SELECT sql FROM sqlite_master WHERE tbl_name = 't8' - } -} {{CREATE TABLE t8(b number(5,10),h,i integer,j BLOB)}} - -#-------------------------------------------------------------------- -# Test cases table-13.* -# -# Test the ability to have default values of CURRENT_TIME, CURRENT_DATE -# and CURRENT_TIMESTAMP. -# -do_test table-13.1 { - execsql { - CREATE TABLE tablet8( - a integer primary key, - tm text DEFAULT CURRENT_TIME, - dt text DEFAULT CURRENT_DATE, - dttm text DEFAULT CURRENT_TIMESTAMP - ); - SELECT * FROM tablet8; - } -} {} -set i 0 -foreach {date time} { - 1976-07-04 12:00:00 - 1994-04-16 14:00:00 - 2000-01-01 00:00:00 - 2003-12-31 12:34:56 -} { - incr i - set sqlite_current_time [clock scan "$date $time" -gmt 1] - # set sqlite_current_time [execsql "SELECT strftime('%s','$date $time')"] - do_test table-13.2.$i { - execsql " - INSERT INTO tablet8(a) VALUES($i); - SELECT tm, dt, dttm FROM tablet8 WHERE a=$i; - " - } [list $time $date [list $date $time]] -} -set sqlite_current_time 0 - -#-------------------------------------------------------------------- -# Test cases table-14.* -# -# Test that a table cannot be created or dropped while other virtual -# machines are active. This is required because otherwise when in -# auto-vacuum mode the btree-layer may need to move the root-pages of -# a table for which there is an open cursor. -# - -# db eval { -# pragma vdbe_trace = 0; -# } -# Try to create a table from within a callback: -unset -nocomplain result -do_test table-14.1 { - set rc [ - catch { - db eval {SELECT * FROM tablet8 LIMIT 1} {} { - db eval {CREATE TABLE t9(a, b, c)} - } - } msg - ] - set result [list $rc $msg] -} {1 {database table is locked}} - -do_test table-14.2 { - execsql { - CREATE TABLE t9(a, b, c) - } -} {} - -# Try to drop a table from within a callback: -do_test table-14.3 { - set rc [ - catch { - db eval {SELECT * FROM tablet8 LIMIT 1} {} { - db eval {DROP TABLE t9;} - } - } msg - ] - set result [list $rc $msg] -} {1 {database table is locked}} - -# Now attach a database and ensure that a table can be created in the -# attached database whilst in a callback from a query on the main database. -do_test table-14.4 { - file delete -force test2.db - file delete -force test2.db-journal - execsql { - attach 'test2.db' as aux; - } - db eval {SELECT * FROM tablet8 LIMIT 1} {} { - db eval {CREATE TABLE aux.t1(a, b, c)} - } -} {} - -# On the other hand, it should be impossible to drop a table when any VMs -# are active. This is because VerifyCookie instructions may have already -# been executed, and btree root-pages may not move after this (which a -# delete table might do). -do_test table-14.4 { - set rc [ - catch { - db eval {SELECT * FROM tablet8 LIMIT 1} {} { - db eval {DROP TABLE aux.t1;} - } - } msg - ] - set result [list $rc $msg] -} {1 {database table is locked}} - -# Create and drop 2000 tables. This is to check that the balance_shallow() -# routine works correctly on the sqlite_master table. At one point it -# contained a bug that would prevent the right-child pointer of the -# child page from being copied to the root page. -# -do_test table-15.1 { - execsql {BEGIN} - for {set i 0} {$i<2000} {incr i} { - execsql "CREATE TABLE tbl$i (a, b, c)" - } - execsql {COMMIT} -} {} -do_test table-15.2 { - execsql {BEGIN} - for {set i 0} {$i<2000} {incr i} { - execsql "DROP TABLE tbl$i" - } - execsql {COMMIT} -} {} - -finish_test - diff --git a/sqlite/test/tableapi.test b/sqlite/test/tableapi.test deleted file mode 100644 index 2355bf6..0000000 --- a/sqlite/test/tableapi.test +++ /dev/null @@ -1,213 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the sqlite_exec_printf() and -# sqlite_get_table_printf() APIs. -# -# $Id: tableapi.test,v 1.10 2005/01/21 03:12:16 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -do_test tableapi-1.0 { - set ::dbx [sqlite3_open test.db] - catch {sqlite_exec_printf $::dbx {DROP TABLE xyz} {}} - sqlite3_exec_printf $::dbx {CREATE TABLE %s(a int, b text)} xyz -} {0 {}} -do_test tableapi-1.1 { - sqlite3_exec_printf $::dbx { - INSERT INTO xyz VALUES(1,'%q') - } {Hi Y'all} -} {0 {}} -do_test tableapi-1.2 { - sqlite3_exec_printf $::dbx {SELECT * FROM xyz} {} -} {0 {a b 1 {Hi Y'all}}} - -do_test tableapi-2.1 { - sqlite3_get_table_printf $::dbx { - BEGIN TRANSACTION; - SELECT * FROM xyz WHERE b='%q' - } {Hi Y'all} -} {0 1 2 a b 1 {Hi Y'all}} -do_test tableapi-2.2 { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz - } {} -} {0 1 2 a b 1 {Hi Y'all}} -do_test tableapi-2.3 { - for {set i 2} {$i<=50} {incr i} { - sqlite3_get_table_printf $::dbx \ - "INSERT INTO xyz VALUES($i,'(%s)')" $i - } - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz ORDER BY a - } {} -} {0 50 2 a b 1 {Hi Y'all} 2 (2) 3 (3) 4 (4) 5 (5) 6 (6) 7 (7) 8 (8) 9 (9) 10 (10) 11 (11) 12 (12) 13 (13) 14 (14) 15 (15) 16 (16) 17 (17) 18 (18) 19 (19) 20 (20) 21 (21) 22 (22) 23 (23) 24 (24) 25 (25) 26 (26) 27 (27) 28 (28) 29 (29) 30 (30) 31 (31) 32 (32) 33 (33) 34 (34) 35 (35) 36 (36) 37 (37) 38 (38) 39 (39) 40 (40) 41 (41) 42 (42) 43 (43) 44 (44) 45 (45) 46 (46) 47 (47) 48 (48) 49 (49) 50 (50)} -do_test tableapi-2.3.1 { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a>49 ORDER BY a - } {} -} {0 1 2 a b 50 (50)} -do_test tableapi-2.3.2 { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a>47 ORDER BY a - } {} -} {0 3 2 a b 48 (48) 49 (49) 50 (50)} -do_test tableapi-2.4 { - set manyquote '''''''' - append manyquote $manyquote - append manyquote $manyquote - append manyquote $manyquote - append manyquote $manyquote - append manyquote $manyquote - append manyquote $manyquote - set ::big_str "$manyquote Hello $manyquote" - sqlite3_get_table_printf $::dbx { - INSERT INTO xyz VALUES(51,'%q') - } $::big_str -} {0 0 0} -do_test tableapi-2.5 { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a>49 ORDER BY a; - } {} -} "0 2 2 a b 50 (50) 51 \173$::big_str\175" -do_test tableapi-2.6 { - sqlite3_get_table_printf $::dbx { - INSERT INTO xyz VALUES(52,NULL) - } {} - ifcapable subquery { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a IN (42,50,52) ORDER BY a DESC - } {} - } else { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a=42 OR a=50 OR a=52 ORDER BY a DESC - } {} - } -} {0 3 2 a b 52 NULL 50 (50) 42 (42)} -do_test tableapi-2.7 { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a>1000 - } {} -} {0 0 0} - -# Repeat all tests with the empty_result_callbacks pragma turned on -# -do_test tableapi-3.1 { - sqlite3_get_table_printf $::dbx { - ROLLBACK; - PRAGMA empty_result_callbacks = ON; - SELECT * FROM xyz WHERE b='%q' - } {Hi Y'all} -} {0 1 2 a b 1 {Hi Y'all}} -do_test tableapi-3.2 { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz - } {} -} {0 1 2 a b 1 {Hi Y'all}} -do_test tableapi-3.3 { - for {set i 2} {$i<=50} {incr i} { - sqlite3_get_table_printf $::dbx \ - "INSERT INTO xyz VALUES($i,'(%s)')" $i - } - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz ORDER BY a - } {} -} {0 50 2 a b 1 {Hi Y'all} 2 (2) 3 (3) 4 (4) 5 (5) 6 (6) 7 (7) 8 (8) 9 (9) 10 (10) 11 (11) 12 (12) 13 (13) 14 (14) 15 (15) 16 (16) 17 (17) 18 (18) 19 (19) 20 (20) 21 (21) 22 (22) 23 (23) 24 (24) 25 (25) 26 (26) 27 (27) 28 (28) 29 (29) 30 (30) 31 (31) 32 (32) 33 (33) 34 (34) 35 (35) 36 (36) 37 (37) 38 (38) 39 (39) 40 (40) 41 (41) 42 (42) 43 (43) 44 (44) 45 (45) 46 (46) 47 (47) 48 (48) 49 (49) 50 (50)} -do_test tableapi-3.3.1 { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a>49 ORDER BY a - } {} -} {0 1 2 a b 50 (50)} -do_test tableapi-3.3.2 { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a>47 ORDER BY a - } {} -} {0 3 2 a b 48 (48) 49 (49) 50 (50)} -do_test tableapi-3.4 { - sqlite3_get_table_printf $::dbx { - INSERT INTO xyz VALUES(51,'%q') - } $::big_str -} {0 0 0} -do_test tableapi-3.5 { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a>49 ORDER BY a; - } {} -} "0 2 2 a b 50 (50) 51 \173$::big_str\175" -do_test tableapi-3.6 { - sqlite3_get_table_printf $::dbx { - INSERT INTO xyz VALUES(52,NULL) - } {} - ifcapable subquery { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a IN (42,50,52) ORDER BY a DESC - } {} - } else { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a=42 OR a=50 OR a=52 ORDER BY a DESC - } {} - } -} {0 3 2 a b 52 NULL 50 (50) 42 (42)} -do_test tableapi-3.7 { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz WHERE a>1000 - } {} -} {0 0 2 a b} - -do_test tableapi-4.1 { - set rc [catch { - sqlite3_get_table_printf $::dbx { - SELECT * FROM xyz; SELECT * FROM sqlite_master - } {} - } msg] - concat $rc $msg -} {0 1 {sqlite3_get_table() called with two or more incompatible queries}} - -# A report on the mailing list says that the sqlite_get_table() api fails -# on queries involving more than 40 columns. The following code attempts -# to test that complaint -# -do_test tableapi-5.1 { - set sql "CREATE TABLE t2(" - set sep "" - for {set i 1} {$i<=100} {incr i} { - append sql ${sep}x$i - set sep , - } - append sql ) - sqlite3_get_table_printf $::dbx $sql {} - set sql "INSERT INTO t2 VALUES(" - set sep "" - for {set i 1} {$i<=100} {incr i} { - append sql ${sep}$i - set sep , - } - append sql ) - sqlite3_get_table_printf $::dbx $sql {} - sqlite3_get_table_printf $::dbx {SELECT * FROM t2} {} -} {0 1 100 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 x32 x33 x34 x35 x36 x37 x38 x39 x40 x41 x42 x43 x44 x45 x46 x47 x48 x49 x50 x51 x52 x53 x54 x55 x56 x57 x58 x59 x60 x61 x62 x63 x64 x65 x66 x67 x68 x69 x70 x71 x72 x73 x74 x75 x76 x77 x78 x79 x80 x81 x82 x83 x84 x85 x86 x87 x88 x89 x90 x91 x92 x93 x94 x95 x96 x97 x98 x99 x100 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100} -do_test tableapi-5.2 { - set sql "INSERT INTO t2 VALUES(" - set sep "" - for {set i 1} {$i<=100} {incr i} { - append sql ${sep}[expr {$i+1000}] - set sep , - } - append sql ) - sqlite3_get_table_printf $::dbx $sql {} - sqlite3_get_table_printf $::dbx {SELECT * FROM t2} {} -} {0 2 100 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 x32 x33 x34 x35 x36 x37 x38 x39 x40 x41 x42 x43 x44 x45 x46 x47 x48 x49 x50 x51 x52 x53 x54 x55 x56 x57 x58 x59 x60 x61 x62 x63 x64 x65 x66 x67 x68 x69 x70 x71 x72 x73 x74 x75 x76 x77 x78 x79 x80 x81 x82 x83 x84 x85 x86 x87 x88 x89 x90 x91 x92 x93 x94 x95 x96 x97 x98 x99 x100 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100} - -do_test tableapi-99.0 { - sqlite3_close $::dbx -} {SQLITE_OK} - -finish_test diff --git a/sqlite/test/tclsqlite.test b/sqlite/test/tclsqlite.test deleted file mode 100644 index 1243d8f..0000000 --- a/sqlite/test/tclsqlite.test +++ /dev/null @@ -1,303 +0,0 @@ -# 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 implements regression tests for TCL interface to the -# SQLite library. -# -# Actually, all tests are based on the TCL interface, so the main -# interface is pretty well tested. This file contains some addition -# tests for fringe issues that the main test suite does not cover. -# -# $Id: tclsqlite.test,v 1.37 2005/01/24 00:28:43 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Check the error messages generated by tclsqlite -# -if {[sqlite3 -has-codec]} { - set r "sqlite_orig HANDLE FILENAME ?-key CODEC-KEY?" -} else { - set r "sqlite3 HANDLE FILENAME ?MODE?" -} -do_test tcl-1.1 { - set v [catch {sqlite3 bogus} msg] - lappend v $msg -} [list 1 "wrong # args: should be \"$r\""] -do_test tcl-1.2 { - set v [catch {db bogus} msg] - lappend v $msg -} {1 {bad option "bogus": must be authorizer, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, errorcode, eval, function, last_insert_rowid, onecolumn, progress, rekey, timeout, total_changes, trace, or version}} -do_test tcl-1.3 { - execsql {CREATE TABLE t1(a int, b int)} - execsql {INSERT INTO t1 VALUES(10,20)} - set v [catch { - db eval {SELECT * FROM t1} data { - error "The error message" - } - } msg] - lappend v $msg -} {1 {The error message}} -do_test tcl-1.4 { - set v [catch { - db eval {SELECT * FROM t2} data { - error "The error message" - } - } msg] - lappend v $msg -} {1 {no such table: t2}} -do_test tcl-1.5 { - set v [catch { - db eval {SELECT * FROM t1} data { - break - } - } msg] - lappend v $msg -} {0 {}} -do_test tcl-1.6 { - set v [catch { - db eval {SELECT * FROM t1} data { - expr x* - } - } msg] - regsub {:.*$} $msg {} msg - lappend v $msg -} {1 {syntax error in expression "x*"}} -do_test tcl-1.7 { - set v [catch {db} msg] - lappend v $msg -} {1 {wrong # args: should be "db SUBCOMMAND ..."}} -if {[catch {db auth {}}]==0} { - do_test tcl-1.8 { - set v [catch {db authorizer 1 2 3} msg] - lappend v $msg - } {1 {wrong # args: should be "db authorizer ?CALLBACK?"}} -} -do_test tcl-1.9 { - set v [catch {db busy 1 2 3} msg] - lappend v $msg -} {1 {wrong # args: should be "db busy CALLBACK"}} -do_test tcl-1.10 { - set v [catch {db progress 1} msg] - lappend v $msg -} {1 {wrong # args: should be "db progress N CALLBACK"}} -do_test tcl-1.11 { - set v [catch {db changes xyz} msg] - lappend v $msg -} {1 {wrong # args: should be "db changes "}} -do_test tcl-1.12 { - set v [catch {db commit_hook a b c} msg] - lappend v $msg -} {1 {wrong # args: should be "db commit_hook ?CALLBACK?"}} -do_test tcl-1.13 { - set v [catch {db complete} msg] - lappend v $msg -} {1 {wrong # args: should be "db complete SQL"}} -do_test tcl-1.14 { - set v [catch {db eval} msg] - lappend v $msg -} {1 {wrong # args: should be "db eval SQL ?ARRAY-NAME? ?SCRIPT?"}} -do_test tcl-1.15 { - set v [catch {db function} msg] - lappend v $msg -} {1 {wrong # args: should be "db function NAME SCRIPT"}} -do_test tcl-1.14 { - set v [catch {db last_insert_rowid xyz} msg] - lappend v $msg -} {1 {wrong # args: should be "db last_insert_rowid "}} -do_test tcl-1.15 { - set v [catch {db rekey} msg] - lappend v $msg -} {1 {wrong # args: should be "db rekey KEY"}} -do_test tcl-1.16 { - set v [catch {db timeout} msg] - lappend v $msg -} {1 {wrong # args: should be "db timeout MILLISECONDS"}} -do_test tcl-1.17 { - set v [catch {db collate} msg] - lappend v $msg -} {1 {wrong # args: should be "db collate NAME SCRIPT"}} -do_test tcl-1.18 { - set v [catch {db collation_needed} msg] - lappend v $msg -} {1 {wrong # args: should be "db collation_needed SCRIPT"}} -do_test tcl-1.19 { - set v [catch {db total_changes xyz} msg] - lappend v $msg -} {1 {wrong # args: should be "db total_changes "}} -do_test tcl-1.20 { - set v [catch {db copy} msg] - lappend v $msg -} {1 {wrong # args: should be "db copy CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"}} - - -if {[sqlite3 -tcl-uses-utf]} { - catch {unset ::result} - do_test tcl-2.1 { - execsql "CREATE TABLE t\u0123x(a int, b\u1235 float)" - } {} - ifcapable schema_pragmas { - do_test tcl-2.2 { - execsql "PRAGMA table_info(t\u0123x)" - } "0 a int 0 {} 0 1 b\u1235 float 0 {} 0" - } - do_test tcl-2.3 { - execsql "INSERT INTO t\u0123x VALUES(1,2.3)" - db eval "SELECT * FROM t\u0123x" result break - set result(*) - } "a b\u1235" -} - - -# Test the onecolumn method -# -do_test tcl-3.1 { - execsql { - INSERT INTO t1 SELECT a*2, b*2 FROM t1; - INSERT INTO t1 SELECT a*2+1, b*2+1 FROM t1; - INSERT INTO t1 SELECT a*2+3, b*2+3 FROM t1; - } - set rc [catch {db onecolumn {SELECT * FROM t1 ORDER BY a}} msg] - lappend rc $msg -} {0 10} -do_test tcl-3.2 { - db onecolumn {SELECT * FROM t1 WHERE a<0} -} {} -do_test tcl-3.3 { - set rc [catch {db onecolumn} errmsg] - lappend rc $errmsg -} {1 {wrong # args: should be "db onecolumn SQL"}} -do_test tcl-3.4 { - set rc [catch {db onecolumn {SELECT bogus}} errmsg] - lappend rc $errmsg -} {1 {no such column: bogus}} -ifcapable {tclvar} { - do_test tcl-3.5 { - set b 50 - set rc [catch {db one {SELECT * FROM t1 WHERE b>$b}} msg] - lappend rc $msg - } {0 41} - do_test tcl-3.6 { - set b 500 - set rc [catch {db one {SELECT * FROM t1 WHERE b>$b}} msg] - lappend rc $msg - } {0 {}} - do_test tcl-3.7 { - set b 500 - set rc [catch {db one { - INSERT INTO t1 VALUES(99,510); - SELECT * FROM t1 WHERE b>$b - }} msg] - lappend rc $msg - } {0 99} -} -ifcapable {!tclvar} { - execsql {INSERT INTO t1 VALUES(99,510)} -} - -# Turn the busy handler on and off -# -do_test tcl-4.1 { - proc busy_callback {cnt} { - break - } - db busy busy_callback - db busy -} {busy_callback} -do_test tcl-4.2 { - db busy {} - db busy -} {} - -ifcapable {tclvar} { - # Parsing of TCL variable names within SQL into bound parameters. - # - do_test tcl-5.1 { - execsql {CREATE TABLE t3(a,b,c)} - catch {unset x} - set x(1) 5 - set x(2) 7 - execsql { - INSERT INTO t3 VALUES($::x(1),$::x(2),$::x(3)); - SELECT * FROM t3 - } - } {5 7 {}} - do_test tcl-5.2 { - execsql { - SELECT typeof(a), typeof(b), typeof(c) FROM t3 - } - } {text text null} - do_test tcl-5.3 { - catch {unset x} - set x [binary format h12 686900686f00] - execsql { - UPDATE t3 SET a=$::x; - } - db eval { - SELECT a FROM t3 - } break - binary scan $a h12 adata - set adata - } {686900686f00} - do_test tcl-5.4 { - execsql { - SELECT typeof(a), typeof(b), typeof(c) FROM t3 - } - } {blob text null} -} - -# Operation of "break" and "continue" within row scripts -# -do_test tcl-6.1 { - db eval {SELECT * FROM t1} { - break - } - lappend a $b -} {10 20} -do_test tcl-6.2 { - set cnt 0 - db eval {SELECT * FROM t1} { - if {$a>40} continue - incr cnt - } - set cnt -} {4} -do_test tcl-6.3 { - set cnt 0 - db eval {SELECT * FROM t1} { - if {$a<40} continue - incr cnt - } - set cnt -} {5} -do_test tcl-6.4 { - proc return_test {x} { - db eval {SELECT * FROM t1} { - if {$a==$x} {return $b} - } - } - return_test 10 -} 20 -do_test tcl-6.5 { - return_test 20 -} 40 -do_test tcl-6.6 { - return_test 99 -} 510 -do_test tcl-6.7 { - return_test 0 -} {} - -do_test tcl-7.1 { - db version - expr 0 -} {0} - -finish_test diff --git a/sqlite/test/tester.tcl b/sqlite/test/tester.tcl deleted file mode 100644 index 1c4cb77..0000000 --- a/sqlite/test/tester.tcl +++ /dev/null @@ -1,424 +0,0 @@ -# 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 implements some common TCL routines used for regression -# testing the SQLite library -# -# $Id: tester.tcl,v 1.48 2005/02/12 08:59:59 danielk1977 Exp $ - -# Make sure tclsqlite3 was compiled correctly. Abort now with an -# error message if not. -# -if {[sqlite3 -tcl-uses-utf]} { - if {"\u1234"=="u1234"} { - puts stderr "***** BUILD PROBLEM *****" - puts stderr "$argv0 was linked against an older version" - puts stderr "of TCL that does not support Unicode, but uses a header" - puts stderr "file (\"tcl.h\") from a new TCL version that does support" - puts stderr "Unicode. This combination causes internal errors." - puts stderr "Recompile using a TCL library and header file that match" - puts stderr "and try again.\n**************************" - exit 1 - } -} else { - if {"\u1234"!="u1234"} { - puts stderr "***** BUILD PROBLEM *****" - puts stderr "$argv0 was linked against an newer version" - puts stderr "of TCL that supports Unicode, but uses a header file" - puts stderr "(\"tcl.h\") from a old TCL version that does not support" - puts stderr "Unicode. This combination causes internal errors." - puts stderr "Recompile using a TCL library and header file that match" - puts stderr "and try again.\n**************************" - exit 1 - } -} - -set tcl_precision 15 - -# Use the pager codec if it is available -# -if {[sqlite3 -has-codec] && [info command sqlite_orig]==""} { - rename sqlite3 sqlite_orig - proc sqlite3 {args} { - if {[llength $args]==2 && [string index [lindex $args 0] 0]!="-"} { - lappend args -key {xyzzy} - } - uplevel 1 sqlite_orig $args - } -} - - -# Create a test database -# -catch {db close} -file delete -force test.db -file delete -force test.db-journal -set ::DB [sqlite3 db ./test.db] -if {[info exists ::SETUP_SQL]} { - db eval $::SETUP_SQL -} - -# Abort early if this script has been run before. -# -if {[info exists nTest]} return - -# Set the test counters to zero -# -set nErr 0 -set nTest 0 -set nProb 0 -set skip_test 0 -set failList {} -set maxErr 1000 - -# Invoke the do_test procedure to run a single test -# -proc do_test {name cmd expected} { - global argv nErr nTest skip_test maxErr - if {$skip_test} { - set skip_test 0 - return - } - if {[llength $argv]==0} { - set go 1 - } else { - set go 0 - foreach pattern $argv { - if {[string match $pattern $name]} { - set go 1 - break - } - } - } - if {!$go} return - incr nTest - puts -nonewline $name... - flush stdout - if {[catch {uplevel #0 "$cmd;\n"} result]} { - puts "\nError: $result" - incr nErr - lappend ::failList $name - if {$nErr>$maxErr} {puts "*** Giving up..."; finalize_testing} - } elseif {[string compare $result $expected]} { - puts "\nExpected: \[$expected\]\n Got: \[$result\]" - incr nErr - lappend ::failList $name - if {$nErr>=$maxErr} {puts "*** Giving up..."; finalize_testing} - } else { - puts " Ok" - } -} - -# The procedure uses the special "sqlite_malloc_stat" command -# (which is only available if SQLite is compiled with -DSQLITE_DEBUG=1) -# to see how many malloc()s have not been free()ed. The number -# of surplus malloc()s is stored in the global variable $::Leak. -# If the value in $::Leak grows, it may mean there is a memory leak -# in the library. -# -proc memleak_check {} { - if {[info command sqlite_malloc_stat]!=""} { - set r [sqlite_malloc_stat] - set ::Leak [expr {[lindex $r 0]-[lindex $r 1]}] - } -} - -# Run this routine last -# -proc finish_test {} { - finalize_testing -} -proc finalize_testing {} { - global nTest nErr nProb sqlite_open_file_count - if {$nErr==0} memleak_check - catch {db close} - puts "$nErr errors out of $nTest tests" - puts "Failures on these tests: $::failList" - if {$nProb>0} { - puts "$nProb probabilistic tests also failed, but this does" - puts "not necessarily indicate a malfunction." - } - if 0 { - if {$sqlite_open_file_count} { - puts "$sqlite_open_file_count files were left open" - incr nErr - } - } - exit [expr {$nErr>0}] -} - -# A procedure to execute SQL -# -proc execsql {sql {db db}} { - # puts "SQL = $sql" - return [$db eval $sql] -} - -# Execute SQL and catch exceptions. -# -proc catchsql {sql {db db}} { - # puts "SQL = $sql" - set r [catch {$db eval $sql} msg] - lappend r $msg - return $r -} - -# Do an VDBE code dump on the SQL given -# -proc explain {sql {db db}} { - puts "" - puts "addr opcode p1 p2 p3 " - puts "---- ------------ ------ ------ ---------------" - $db eval "explain $sql" {} { - puts [format {%-4d %-12.12s %-6d %-6d %s} $addr $opcode $p1 $p2 $p3] - } -} - -# Another procedure to execute SQL. This one includes the field -# names in the returned list. -# -proc execsql2 {sql} { - set result {} - db eval $sql data { - foreach f $data(*) { - lappend result $f $data($f) - } - } - return $result -} - -# Use the non-callback API to execute multiple SQL statements -# -proc stepsql {dbptr sql} { - set sql [string trim $sql] - set r 0 - while {[string length $sql]>0} { - if {[catch {sqlite3_prepare $dbptr $sql -1 sqltail} vm]} { - return [list 1 $vm] - } - set sql [string trim $sqltail] -# while {[sqlite_step $vm N VAL COL]=="SQLITE_ROW"} { -# foreach v $VAL {lappend r $v} -# } - while {[sqlite3_step $vm]=="SQLITE_ROW"} { - for {set i 0} {$i<[sqlite3_data_count $vm]} {incr i} { - lappend r [sqlite3_column_text $vm $i] - } - } - if {[catch {sqlite3_finalize $vm} errmsg]} { - return [list 1 $errmsg] - } - } - return $r -} - -# Delete a file or directory -# -proc forcedelete {filename} { - if {[catch {file delete -force $filename}]} { - exec rm -rf $filename - } -} - -# Do an integrity check of the entire database -# -proc integrity_check {name} { - ifcapable integrityck { - do_test $name { - execsql {PRAGMA integrity_check} - } {ok} - } -} - -# Evaluate a boolean expression of capabilities. If true, execute the -# code. Omit the code if false. -# -proc ifcapable {expr code {else ""} {elsecode ""}} { - regsub -all {[a-z_0-9]+} $expr {$::sqlite_options(&)} e2 - if ($e2) { - set c [catch {uplevel 1 $code} r] - } else { - set c [catch {uplevel 1 $elsecode} r] - } - return -code $c $r -} - -# This proc execs a seperate process that crashes midway through executing -# the SQL script $sql on database test.db. -# -# The crash occurs during a sync() of file $crashfile. When the crash -# occurs a random subset of all unsynced writes made by the process are -# written into the files on disk. Argument $crashdelay indicates the -# number of file syncs to wait before crashing. -# -# The return value is a list of two elements. The first element is a -# boolean, indicating whether or not the process actually crashed or -# reported some other error. The second element in the returned list is the -# error message. This is "child process exited abnormally" if the crash -# occured. -# -proc crashsql {crashdelay crashfile sql} { - if {$::tcl_platform(platform)!="unix"} { - error "crashsql should only be used on unix" - } - set cfile [file join [pwd] $crashfile] - - set f [open crash.tcl w] - puts $f "sqlite3_crashparams $crashdelay $cfile" - puts $f "sqlite3 db test.db" - puts $f "db eval {pragma cache_size = 10}" - puts $f "db eval {" - puts $f "$sql" - puts $f "}" - close $f - - set r [catch { - exec [file join . crashtest] crash.tcl >@stdout - } msg] - lappend r $msg -} - -# Usage: do_ioerr_test -# -# This proc is used to implement test cases that check that IO errors -# are correctly handled. The first argument, , is an integer -# used to name the tests executed by this proc. Options are as follows: -# -# -tclprep TCL script to run to prepare test. -# -sqlprep SQL script to run to prepare test. -# -tclbody TCL script to run with IO error simulation. -# -sqlbody TCL script to run with IO error simulation. -# -exclude List of 'N' values not to test. -# -start Value of 'N' to begin with (default 1) -# -# -cksum Boolean. If true, test that the database does -# not change during the execution of the test case. -# -proc do_ioerr_test {testname args} { - - set ::ioerropts(-start) 1 - set ::ioerropts(-cksum) 0 - - array set ::ioerropts $args - - set ::go 1 - for {set n $::ioerropts(-start)} {$::go} {incr n} { - - # Skip this IO error if it was specified with the "-exclude" option. - if {[info exists ::ioerropts(-exclude)]} { - if {[lsearch $::ioerropts(-exclude) $n]!=-1} continue - } - - # Delete the files test.db and test2.db, then execute the TCL and - # SQL (in that order) to prepare for the test case. - do_test $testname.$n.1 { - set ::sqlite_io_error_pending 0 - catch {db close} - catch {file delete -force test.db} - catch {file delete -force test.db-journal} - catch {file delete -force test2.db} - catch {file delete -force test2.db-journal} - set ::DB [sqlite3 db test.db] - if {[info exists ::ioerropts(-tclprep)]} { - eval $::ioerropts(-tclprep) - } - if {[info exists ::ioerropts(-sqlprep)]} { - execsql $::ioerropts(-sqlprep) - } - expr 0 - } {0} - - # Read the 'checksum' of the database. - if {$::ioerropts(-cksum)} { - set checksum [cksum] - } - - # Set the Nth IO error to fail. - do_test $testname.$n.2 [subst { - set ::sqlite_io_error_pending $n - }] $n - - # Create a single TCL script from the TCL and SQL specified - # as the body of the test. - set ::ioerrorbody {} - if {[info exists ::ioerropts(-tclbody)]} { - append ::ioerrorbody "$::ioerropts(-tclbody)\n" - } - if {[info exists ::ioerropts(-sqlbody)]} { - append ::ioerrorbody "db eval {$::ioerropts(-sqlbody)}" - } - - # Execute the TCL Script created in the above block. If - # there are at least N IO operations performed by SQLite as - # a result of the script, the Nth will fail. - do_test $testname.$n.3 { - set r [catch $::ioerrorbody msg] - set ::go [expr {$::sqlite_io_error_pending<=0}] - set s [expr $::sqlite_io_error_pending>0] - # puts "$::sqlite_io_error_pending $r $msg" - expr { ($s && !$r) || (!$s && $r) } - # expr {$::sqlite_io_error_pending>0 || $r!=0} - } {1} - - # If an IO error occured, then the checksum of the database should - # be the same as before the script that caused the IO error was run. - if {$::go && $::ioerropts(-cksum)} { - do_test $testname.$n.4 { - catch {db close} - set ::DB [sqlite3 db test.db] - cksum - } $checksum - } - - } - set ::sqlite_io_error_pending 0 - unset ::ioerropts -} - -# Return a checksum based on the contents of database 'db'. -# -proc cksum {{db db}} { - set txt [$db eval { - SELECT name, type, sql FROM sqlite_master order by name - }]\n - foreach tbl [$db eval { - SELECT name FROM sqlite_master WHERE type='table' order by name - }] { - append txt [$db eval "SELECT * FROM $tbl"]\n - } - foreach prag {default_synchronous default_cache_size} { - append txt $prag-[$db eval "PRAGMA $prag"]\n - } - set cksum [string length $txt]-[md5 $txt] - # puts $cksum-[file size test.db] - return $cksum -} - -# Copy file $from into $to. This is used because some versions of -# TCL for windows (notably the 8.4.1 binary package shipped with the -# current mingw release) have a broken "file copy" command. -# -proc copy_file {from to} { - if {$::tcl_platform(platform)=="unix"} { - file copy -force $from $to - } else { - set f [open $from] - fconfigure $f -translation binary - set t [open $to w] - fconfigure $t -translation binary - puts -nonewline $t [read $f [file size $from]] - close $t - close $f - } -} - -# If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set -# to non-zero, then set the global variable $AUTOVACUUM to 1. -set AUTOVACUUM $sqlite_options(default_autovacuum) diff --git a/sqlite/test/trigger1.test b/sqlite/test/trigger1.test deleted file mode 100644 index e80579e..0000000 --- a/sqlite/test/trigger1.test +++ /dev/null @@ -1,575 +0,0 @@ -# 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 tests creating and dropping triggers, and interaction thereof -# with the database COMMIT/ROLLBACK logic. -# -# 1. CREATE and DROP TRIGGER tests -# trig-1.1: Error if table does not exist -# trig-1.2: Error if trigger already exists -# trig-1.3: Created triggers are deleted if the transaction is rolled back -# trig-1.4: DROP TRIGGER removes trigger -# trig-1.5: Dropped triggers are restored if the transaction is rolled back -# trig-1.6: Error if dropped trigger doesn't exist -# trig-1.7: Dropping the table automatically drops all triggers -# trig-1.8: A trigger created on a TEMP table is not inserted into sqlite_master -# trig-1.9: Ensure that we cannot create a trigger on sqlite_master -# trig-1.10: -# trig-1.11: -# trig-1.12: Ensure that INSTEAD OF triggers cannot be created on tables -# trig-1.13: Ensure that AFTER triggers cannot be created on views -# trig-1.14: Ensure that BEFORE triggers cannot be created on views -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -ifcapable {!trigger} { - finish_test - return -} - -do_test trigger1-1.1.1 { - catchsql { - CREATE TRIGGER trig UPDATE ON no_such_table BEGIN - SELECT * from sqlite_master; - END; - } -} {1 {no such table: main.no_such_table}} -do_test trigger1-1.1.2 { - catchsql { - CREATE TEMP TRIGGER trig UPDATE ON no_such_table BEGIN - SELECT * from sqlite_master; - END; - } -} {1 {no such table: no_such_table}} - -execsql { - CREATE TABLE t1(a); -} -execsql { - CREATE TRIGGER tr1 INSERT ON t1 BEGIN - INSERT INTO t1 values(1); - END; -} -do_test trigger1-1.2 { - catchsql { - CREATE TRIGGER tr1 DELETE ON t1 BEGIN - SELECT * FROM sqlite_master; - END - } -} {1 {trigger tr1 already exists}} - -do_test trigger1-1.3 { - catchsql { - BEGIN; - CREATE TRIGGER tr2 INSERT ON t1 BEGIN - SELECT * from sqlite_master; END; - ROLLBACK; - CREATE TRIGGER tr2 INSERT ON t1 BEGIN - SELECT * from sqlite_master; END; - } -} {0 {}} - -do_test trigger1-1.4 { - catchsql { - DROP TRIGGER tr1; - CREATE TRIGGER tr1 DELETE ON t1 BEGIN - SELECT * FROM sqlite_master; - END - } -} {0 {}} - -do_test trigger1-1.5 { - execsql { - BEGIN; - DROP TRIGGER tr2; - ROLLBACK; - DROP TRIGGER tr2; - } -} {} - -do_test trigger1-1.6 { - catchsql { - DROP TRIGGER biggles; - } -} {1 {no such trigger: biggles}} - -do_test trigger1-1.7 { - catchsql { - DROP TABLE t1; - DROP TRIGGER tr1; - } -} {1 {no such trigger: tr1}} - -execsql { - CREATE TEMP TABLE temp_table(a); -} -do_test trigger1-1.8 { - execsql { - CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN - SELECT * from sqlite_master; - END; - SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig'; - } -} {0} - -do_test trigger1-1.9 { - catchsql { - CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN - SELECT * FROM sqlite_master; - END; - } -} {1 {cannot create trigger on system table}} - -# Check to make sure that a DELETE statement within the body of -# a trigger does not mess up the DELETE that caused the trigger to -# run in the first place. -# -do_test trigger1-1.10 { - execsql { - create table t1(a,b); - insert into t1 values(1,'a'); - insert into t1 values(2,'b'); - insert into t1 values(3,'c'); - insert into t1 values(4,'d'); - create trigger r1 after delete on t1 for each row begin - delete from t1 WHERE a=old.a+2; - end; - delete from t1 where a=1 OR a=3; - select * from t1; - drop table t1; - } -} {2 b 4 d} - -do_test trigger1-1.11 { - execsql { - create table t1(a,b); - insert into t1 values(1,'a'); - insert into t1 values(2,'b'); - insert into t1 values(3,'c'); - insert into t1 values(4,'d'); - create trigger r1 after update on t1 for each row begin - delete from t1 WHERE a=old.a+2; - end; - update t1 set b='x-' || b where a=1 OR a=3; - select * from t1; - drop table t1; - } -} {1 x-a 2 b 4 d} - -# Ensure that we cannot create INSTEAD OF triggers on tables -do_test trigger1-1.12 { - catchsql { - create table t1(a,b); - create trigger t1t instead of update on t1 for each row begin - delete from t1 WHERE a=old.a+2; - end; - } -} {1 {cannot create INSTEAD OF trigger on table: main.t1}} - -ifcapable view { -# Ensure that we cannot create BEFORE triggers on views -do_test trigger1-1.13 { - catchsql { - create view v1 as select * from t1; - create trigger v1t before update on v1 for each row begin - delete from t1 WHERE a=old.a+2; - end; - } -} {1 {cannot create BEFORE trigger on view: main.v1}} -# Ensure that we cannot create AFTER triggers on views -do_test trigger1-1.14 { - catchsql { - drop view v1; - create view v1 as select * from t1; - create trigger v1t AFTER update on v1 for each row begin - delete from t1 WHERE a=old.a+2; - end; - } -} {1 {cannot create AFTER trigger on view: main.v1}} -} ;# ifcapable view - -# Check for memory leaks in the trigger parser -# -do_test trigger1-2.1 { - catchsql { - CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN - SELECT * FROM; -- Syntax error - END; - } -} {1 {near ";": syntax error}} -do_test trigger1-2.2 { - catchsql { - CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN - SELECT * FROM t1; - SELECT * FROM; -- Syntax error - END; - } -} {1 {near ";": syntax error}} - -# Create a trigger that refers to a table that might not exist. -# -do_test trigger1-3.1 { - execsql { - CREATE TEMP TABLE t2(x,y); - } - catchsql { - CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN - INSERT INTO t2 VALUES(NEW.a,NEW.b); - END; - } -} {0 {}} -do_test trigger-3.2 { - catchsql { - INSERT INTO t1 VALUES(1,2); - SELECT * FROM t2; - } -} {1 {no such table: main.t2}} -do_test trigger-3.3 { - db close - set rc [catch {sqlite3 db test.db} err] - if {$rc} {lappend rc $err} - set rc -} {0} -do_test trigger-3.4 { - catchsql { - INSERT INTO t1 VALUES(1,2); - SELECT * FROM t2; - } -} {1 {no such table: main.t2}} -do_test trigger-3.5 { - catchsql { - CREATE TEMP TABLE t2(x,y); - INSERT INTO t1 VALUES(1,2); - SELECT * FROM t2; - } -} {1 {no such table: main.t2}} -do_test trigger-3.6 { - catchsql { - DROP TRIGGER r1; - CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN - INSERT INTO t2 VALUES(NEW.a,NEW.b); - END; - INSERT INTO t1 VALUES(1,2); - SELECT * FROM t2; - } -} {0 {1 2}} -do_test trigger-3.7 { - execsql { - DROP TABLE t2; - CREATE TABLE t2(x,y); - SELECT * FROM t2; - } -} {} - -# There are two versions of trigger-3.8 and trigger-3.9. One that uses -# compound SELECT statements, and another that does not. -ifcapable compound { -do_test trigger-3.8 { - execsql { - INSERT INTO t1 VALUES(3,4); - SELECT * FROM t1 UNION ALL SELECT * FROM t2; - } -} {1 2 3 4 3 4} -do_test trigger-3.9 { - db close - sqlite3 db test.db - execsql { - INSERT INTO t1 VALUES(5,6); - SELECT * FROM t1 UNION ALL SELECT * FROM t2; - } -} {1 2 3 4 5 6 3 4} -} ;# ifcapable compound -ifcapable !compound { -do_test trigger-3.8 { - execsql { - INSERT INTO t1 VALUES(3,4); - SELECT * FROM t1; - SELECT * FROM t2; - } -} {1 2 3 4 3 4} -do_test trigger-3.9 { - db close - sqlite3 db test.db - execsql { - INSERT INTO t1 VALUES(5,6); - SELECT * FROM t1; - SELECT * FROM t2; - } -} {1 2 3 4 5 6 3 4} -} ;# ifcapable !compound - -do_test trigger-4.1 { - execsql { - CREATE TEMP TRIGGER r1 BEFORE INSERT ON t1 BEGIN - INSERT INTO t2 VALUES(NEW.a,NEW.b); - END; - INSERT INTO t1 VALUES(7,8); - SELECT * FROM t2; - } -} {3 4 7 8} -do_test trigger-4.2 { - sqlite3 db2 test.db - execsql { - INSERT INTO t1 VALUES(9,10); - } db2; - db2 close - execsql { - SELECT * FROM t2; - } -} {3 4 7 8} -do_test trigger-4.3 { - execsql { - DROP TABLE t1; - SELECT * FROM t2; - }; -} {3 4 7 8} -do_test trigger-4.4 { - db close - sqlite3 db test.db - execsql { - SELECT * FROM t2; - }; -} {3 4 7 8} - -integrity_check trigger-5.1 - -# Create a trigger with the same name as a table. Make sure the -# trigger works. Then drop the trigger. Make sure the table is -# still there. -# -set view_v1 {} -ifcapable view { - set view_v1 {view v1} -} -do_test trigger-6.1 { - execsql {SELECT type, name FROM sqlite_master} -} [concat $view_v1 {table t2}] -do_test trigger-6.2 { - execsql { - CREATE TRIGGER t2 BEFORE DELETE ON t2 BEGIN - SELECT RAISE(ABORT,'deletes are not allows'); - END; - SELECT type, name FROM sqlite_master; - } -} [concat $view_v1 {table t2 trigger t2}] -do_test trigger-6.3 { - catchsql {DELETE FROM t2} -} {1 {deletes are not allows}} -do_test trigger-6.4 { - execsql {SELECT * FROM t2} -} {3 4 7 8} -do_test trigger-6.5 { - db close - sqlite3 db test.db - execsql {SELECT type, name FROM sqlite_master} -} [concat $view_v1 {table t2 trigger t2}] -do_test trigger-6.6 { - execsql { - DROP TRIGGER t2; - SELECT type, name FROM sqlite_master; - } -} [concat $view_v1 {table t2}] -do_test trigger-6.7 { - execsql {SELECT * FROM t2} -} {3 4 7 8} -do_test trigger-6.8 { - db close - sqlite3 db test.db - execsql {SELECT * FROM t2} -} {3 4 7 8} - -integrity_check trigger-7.1 - -# Check to make sure the name of a trigger can be quoted so that keywords -# can be used as trigger names. Ticket #468 -# -do_test trigger-8.1 { - execsql { - CREATE TRIGGER 'trigger' AFTER INSERT ON t2 BEGIN SELECT 1; END; - SELECT name FROM sqlite_master WHERE type='trigger'; - } -} {trigger} -do_test trigger-8.2 { - execsql { - DROP TRIGGER 'trigger'; - SELECT name FROM sqlite_master WHERE type='trigger'; - } -} {} -do_test trigger-8.3 { - execsql { - CREATE TRIGGER "trigger" AFTER INSERT ON t2 BEGIN SELECT 1; END; - SELECT name FROM sqlite_master WHERE type='trigger'; - } -} {trigger} -do_test trigger-8.4 { - execsql { - DROP TRIGGER "trigger"; - SELECT name FROM sqlite_master WHERE type='trigger'; - } -} {} -do_test trigger-8.5 { - execsql { - CREATE TRIGGER [trigger] AFTER INSERT ON t2 BEGIN SELECT 1; END; - SELECT name FROM sqlite_master WHERE type='trigger'; - } -} {trigger} -do_test trigger-8.6 { - execsql { - DROP TRIGGER [trigger]; - SELECT name FROM sqlite_master WHERE type='trigger'; - } -} {} - -# Make sure REPLACE works inside of triggers. -# -# There are two versions of trigger-9.1 and trigger-9.2. One that uses -# compound SELECT statements, and another that does not. -ifcapable compound { -do_test trigger-9.1 { - execsql { - CREATE TABLE t3(a,b); - CREATE TABLE t4(x UNIQUE, b); - CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN - REPLACE INTO t4 VALUES(new.a,new.b); - END; - INSERT INTO t3 VALUES(1,2); - SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4; - } -} {1 2 99 99 1 2} -do_test trigger-9.2 { - execsql { - INSERT INTO t3 VALUES(1,3); - SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4; - } -} {1 2 1 3 99 99 1 3} -} -ifcapable !compound { -do_test trigger-9.1 { - execsql { - CREATE TABLE t3(a,b); - CREATE TABLE t4(x UNIQUE, b); - CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN - REPLACE INTO t4 VALUES(new.a,new.b); - END; - INSERT INTO t3 VALUES(1,2); - SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4; - } -} {1 2 99 99 1 2} -do_test trigger-9.2 { - execsql { - INSERT INTO t3 VALUES(1,3); - SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4; - } -} {1 2 1 3 99 99 1 3} -} - -execsql { - DROP TABLE t2; - DROP TABLE t3; - DROP TABLE t4; -} - -# Ticket #764. At one stage TEMP triggers would fail to re-install when the -# schema was reloaded. The following tests ensure that TEMP triggers are -# correctly re-installed. -# -# Also verify that references within trigger programs are resolved at -# statement compile time, not trigger installation time. This means, for -# example, that you can drop and re-create tables referenced by triggers. -do_test trigger-10.0 { - file delete -force test2.db - file delete -force test2.db-journal - execsql { - ATTACH 'test2.db' AS aux; - } -} {} -do_test trigger-10.1 { - execsql { - CREATE TABLE main.t4(a, b, c); - CREATE TABLE temp.t4(a, b, c); - CREATE TABLE aux.t4(a, b, c); - CREATE TABLE insert_log(db, a, b, c); - } -} {} -do_test trigger-10.2 { - execsql { - CREATE TEMP TRIGGER trig1 AFTER INSERT ON main.t4 BEGIN - INSERT INTO insert_log VALUES('main', new.a, new.b, new.c); - END; - CREATE TEMP TRIGGER trig2 AFTER INSERT ON temp.t4 BEGIN - INSERT INTO insert_log VALUES('temp', new.a, new.b, new.c); - END; - CREATE TEMP TRIGGER trig3 AFTER INSERT ON aux.t4 BEGIN - INSERT INTO insert_log VALUES('aux', new.a, new.b, new.c); - END; - } -} {} -do_test trigger-10.3 { - execsql { - INSERT INTO main.t4 VALUES(1, 2, 3); - INSERT INTO temp.t4 VALUES(4, 5, 6); - INSERT INTO aux.t4 VALUES(7, 8, 9); - } -} {} -do_test trigger-10.4 { - execsql { - SELECT * FROM insert_log; - } -} {main 1 2 3 temp 4 5 6 aux 7 8 9} -do_test trigger-10.5 { - execsql { - BEGIN; - INSERT INTO main.t4 VALUES(1, 2, 3); - INSERT INTO temp.t4 VALUES(4, 5, 6); - INSERT INTO aux.t4 VALUES(7, 8, 9); - ROLLBACK; - } -} {} -do_test trigger-10.6 { - execsql { - SELECT * FROM insert_log; - } -} {main 1 2 3 temp 4 5 6 aux 7 8 9} -do_test trigger-10.7 { - execsql { - DELETE FROM insert_log; - INSERT INTO main.t4 VALUES(11, 12, 13); - INSERT INTO temp.t4 VALUES(14, 15, 16); - INSERT INTO aux.t4 VALUES(17, 18, 19); - } -} {} -do_test trigger-10.8 { - execsql { - SELECT * FROM insert_log; - } -} {main 11 12 13 temp 14 15 16 aux 17 18 19} -do_test trigger-10.8 { -# Drop and re-create the insert_log table in a different database. Note -# that we can change the column names because the trigger programs don't -# use them explicitly. - execsql { - DROP TABLE insert_log; - CREATE TABLE aux.insert_log(db, d, e, f); - } -} {} -do_test trigger-10.10 { - execsql { - INSERT INTO main.t4 VALUES(21, 22, 23); - INSERT INTO temp.t4 VALUES(24, 25, 26); - INSERT INTO aux.t4 VALUES(27, 28, 29); - } -} {} -do_test trigger-10.11 { - execsql { - SELECT * FROM insert_log; - } -} {main 21 22 23 temp 24 25 26 aux 27 28 29} - -finish_test diff --git a/sqlite/test/trigger2.test b/sqlite/test/trigger2.test deleted file mode 100644 index 9dc03ef..0000000 --- a/sqlite/test/trigger2.test +++ /dev/null @@ -1,728 +0,0 @@ -# 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. -# -#*********************************************************************** -# -# Regression testing of FOR EACH ROW table triggers -# -# 1. Trigger execution order tests. -# These tests ensure that BEFORE and AFTER triggers are fired at the correct -# times relative to each other and the triggering statement. -# -# trigger2-1.1.*: ON UPDATE trigger execution model. -# trigger2-1.2.*: DELETE trigger execution model. -# trigger2-1.3.*: INSERT trigger execution model. -# -# 2. Trigger program execution tests. -# These tests ensure that trigger programs execute correctly (ie. that a -# trigger program can correctly execute INSERT, UPDATE, DELETE * SELECT -# statements, and combinations thereof). -# -# 3. Selective trigger execution -# This tests that conditional triggers (ie. UPDATE OF triggers and triggers -# with WHEN clauses) are fired only fired when they are supposed to be. -# -# trigger2-3.1: UPDATE OF triggers -# trigger2-3.2: WHEN clause -# -# 4. Cascaded trigger execution -# Tests that trigger-programs may cause other triggers to fire. Also that a -# trigger-program is never executed recursively. -# -# trigger2-4.1: Trivial cascading trigger -# trigger2-4.2: Trivial recursive trigger handling -# -# 5. Count changes behaviour. -# Verify that rows altered by triggers are not included in the return value -# of the "count changes" interface. -# -# 6. ON CONFLICT clause handling -# trigger2-6.1[a-f]: INSERT statements -# trigger2-6.2[a-f]: UPDATE statements -# -# 7. & 8. Triggers on views fire correctly. -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -ifcapable {!trigger} { - finish_test - return -} - -# 1. -ifcapable subquery { - set ii 0 - foreach tbl_defn { - {CREATE TEMP TABLE tbl (a, b);} - {CREATE TABLE tbl (a, b);} - {CREATE TABLE tbl (a INTEGER PRIMARY KEY, b);} - {CREATE TEMPORARY TABLE tbl (a INTEGER PRIMARY KEY, b);} - {CREATE TABLE tbl (a, b PRIMARY KEY);} - {CREATE TABLE tbl (a, b); CREATE INDEX tbl_idx ON tbl(b);} - {CREATE TEMP TABLE tbl (a, b); CREATE INDEX tbl_idx ON tbl(b);} - } { - incr ii - catchsql { DROP INDEX tbl_idx; } - catchsql { - DROP TABLE rlog; - DROP TABLE clog; - DROP TABLE tbl; - DROP TABLE other_tbl; - } - - execsql $tbl_defn - - execsql { - INSERT INTO tbl VALUES(1, 2); - INSERT INTO tbl VALUES(3, 4); - - CREATE TABLE rlog (idx, old_a, old_b, db_sum_a, db_sum_b, new_a, new_b); - CREATE TABLE clog (idx, old_a, old_b, db_sum_a, db_sum_b, new_a, new_b); - - CREATE TRIGGER before_update_row BEFORE UPDATE ON tbl FOR EACH ROW - BEGIN - INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), - old.a, old.b, - (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl), - new.a, new.b); - END; - - CREATE TRIGGER after_update_row AFTER UPDATE ON tbl FOR EACH ROW - BEGIN - INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), - old.a, old.b, - (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl), - new.a, new.b); - END; - - CREATE TRIGGER conditional_update_row AFTER UPDATE ON tbl FOR EACH ROW - WHEN old.a = 1 - BEGIN - INSERT INTO clog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM clog), - old.a, old.b, - (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl), - new.a, new.b); - END; - } - - do_test trigger2-1.$ii.1 { - set r {} - foreach v [execsql { - UPDATE tbl SET a = a * 10, b = b * 10; - SELECT * FROM rlog ORDER BY idx; - SELECT * FROM clog ORDER BY idx; - }] { - lappend r [expr {int($v)}] - } - set r - } [list 1 1 2 4 6 10 20 \ - 2 1 2 13 24 10 20 \ - 3 3 4 13 24 30 40 \ - 4 3 4 40 60 30 40 \ - 1 1 2 13 24 10 20 ] - - execsql { - DELETE FROM rlog; - DELETE FROM tbl; - INSERT INTO tbl VALUES (100, 100); - INSERT INTO tbl VALUES (300, 200); - CREATE TRIGGER delete_before_row BEFORE DELETE ON tbl FOR EACH ROW - BEGIN - INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), - old.a, old.b, - (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl), - 0, 0); - END; - - CREATE TRIGGER delete_after_row AFTER DELETE ON tbl FOR EACH ROW - BEGIN - INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), - old.a, old.b, - (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl), - 0, 0); - END; - } - do_test trigger2-1.$ii.2 { - set r {} - foreach v [execsql { - DELETE FROM tbl; - SELECT * FROM rlog; - }] { - lappend r [expr {int($v)}] - } - set r - } [list 1 100 100 400 300 0 0 \ - 2 100 100 300 200 0 0 \ - 3 300 200 300 200 0 0 \ - 4 300 200 0 0 0 0 ] - - execsql { - DELETE FROM rlog; - CREATE TRIGGER insert_before_row BEFORE INSERT ON tbl FOR EACH ROW - BEGIN - INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), - 0, 0, - (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl), - new.a, new.b); - END; - - CREATE TRIGGER insert_after_row AFTER INSERT ON tbl FOR EACH ROW - BEGIN - INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), - 0, 0, - (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl), - new.a, new.b); - END; - } - do_test trigger2-1.$ii.3 { - execsql { - - CREATE TABLE other_tbl(a, b); - INSERT INTO other_tbl VALUES(1, 2); - INSERT INTO other_tbl VALUES(3, 4); - -- INSERT INTO tbl SELECT * FROM other_tbl; - INSERT INTO tbl VALUES(5, 6); - DROP TABLE other_tbl; - - SELECT * FROM rlog; - } - } [list 1 0 0 0.0 0.0 5 6 \ - 2 0 0 5.0 6.0 5 6 ] - - integrity_check trigger2-1.$ii.4 - } - catchsql { - DROP TABLE rlog; - DROP TABLE clog; - DROP TABLE tbl; - DROP TABLE other_tbl; - } -} - -# 2. -set ii 0 -foreach tr_program { - {UPDATE tbl SET b = old.b;} - {INSERT INTO log VALUES(new.c, 2, 3);} - {DELETE FROM log WHERE a = 1;} - {INSERT INTO tbl VALUES(500, new.b * 10, 700); - UPDATE tbl SET c = old.c; - DELETE FROM log;} - {INSERT INTO log select * from tbl;} -} { - foreach test_varset [ list \ - { - set statement {UPDATE tbl SET c = 10 WHERE a = 1;} - set prep {INSERT INTO tbl VALUES(1, 2, 3);} - set newC 10 - set newB 2 - set newA 1 - set oldA 1 - set oldB 2 - set oldC 3 - } \ - { - set statement {DELETE FROM tbl WHERE a = 1;} - set prep {INSERT INTO tbl VALUES(1, 2, 3);} - set oldA 1 - set oldB 2 - set oldC 3 - } \ - { - set statement {INSERT INTO tbl VALUES(1, 2, 3);} - set newA 1 - set newB 2 - set newC 3 - } - ] \ - { - set statement {} - set prep {} - set newA {''} - set newB {''} - set newC {''} - set oldA {''} - set oldB {''} - set oldC {''} - - incr ii - - eval $test_varset - - set statement_type [string range $statement 0 5] - set tr_program_fixed $tr_program - if {$statement_type == "DELETE"} { - regsub -all new\.a $tr_program_fixed {''} tr_program_fixed - regsub -all new\.b $tr_program_fixed {''} tr_program_fixed - regsub -all new\.c $tr_program_fixed {''} tr_program_fixed - } - if {$statement_type == "INSERT"} { - regsub -all old\.a $tr_program_fixed {''} tr_program_fixed - regsub -all old\.b $tr_program_fixed {''} tr_program_fixed - regsub -all old\.c $tr_program_fixed {''} tr_program_fixed - } - - - set tr_program_cooked $tr_program - regsub -all new\.a $tr_program_cooked $newA tr_program_cooked - regsub -all new\.b $tr_program_cooked $newB tr_program_cooked - regsub -all new\.c $tr_program_cooked $newC tr_program_cooked - regsub -all old\.a $tr_program_cooked $oldA tr_program_cooked - regsub -all old\.b $tr_program_cooked $oldB tr_program_cooked - regsub -all old\.c $tr_program_cooked $oldC tr_program_cooked - - catchsql { - DROP TABLE tbl; - DROP TABLE log; - } - - execsql { - CREATE TABLE tbl(a PRIMARY KEY, b, c); - CREATE TABLE log(a, b, c); - } - - set query {SELECT * FROM tbl; SELECT * FROM log;} - set prep "$prep; INSERT INTO log VALUES(1, 2, 3);\ - INSERT INTO log VALUES(10, 20, 30);" - -# Check execution of BEFORE programs: - - set before_data [ execsql "$prep $tr_program_cooked $statement $query" ] - - execsql "DELETE FROM tbl; DELETE FROM log; $prep"; - execsql "CREATE TRIGGER the_trigger BEFORE [string range $statement 0 6]\ - ON tbl BEGIN $tr_program_fixed END;" - - do_test trigger2-2.$ii-before "execsql {$statement $query}" $before_data - - execsql "DROP TRIGGER the_trigger;" - execsql "DELETE FROM tbl; DELETE FROM log;" - -# Check execution of AFTER programs - set after_data [ execsql "$prep $statement $tr_program_cooked $query" ] - - execsql "DELETE FROM tbl; DELETE FROM log; $prep"; - execsql "CREATE TRIGGER the_trigger AFTER [string range $statement 0 6]\ - ON tbl BEGIN $tr_program_fixed END;" - - do_test trigger2-2.$ii-after "execsql {$statement $query}" $after_data - execsql "DROP TRIGGER the_trigger;" - - integrity_check trigger2-2.$ii-integrity - } -} -catchsql { - DROP TABLE tbl; - DROP TABLE log; -} - -# 3. - -# trigger2-3.1: UPDATE OF triggers -execsql { - CREATE TABLE tbl (a, b, c, d); - CREATE TABLE log (a); - INSERT INTO log VALUES (0); - INSERT INTO tbl VALUES (0, 0, 0, 0); - INSERT INTO tbl VALUES (1, 0, 0, 0); - CREATE TRIGGER tbl_after_update_cd BEFORE UPDATE OF c, d ON tbl - BEGIN - UPDATE log SET a = a + 1; - END; -} -do_test trigger2-3.1 { - execsql { - UPDATE tbl SET b = 1, c = 10; -- 2 - UPDATE tbl SET b = 10; -- 0 - UPDATE tbl SET d = 4 WHERE a = 0; --1 - UPDATE tbl SET a = 4, b = 10; --0 - SELECT * FROM log; - } -} {3} -execsql { - DROP TABLE tbl; - DROP TABLE log; -} - -# trigger2-3.2: WHEN clause -set when_triggers [list {t1 BEFORE INSERT ON tbl WHEN new.a > 20}] -ifcapable subquery { - lappend when_triggers \ - {t2 BEFORE INSERT ON tbl WHEN (SELECT count(*) FROM tbl) = 0} -} - -execsql { - CREATE TABLE tbl (a, b, c, d); - CREATE TABLE log (a); - INSERT INTO log VALUES (0); -} - -foreach trig $when_triggers { - execsql "CREATE TRIGGER $trig BEGIN UPDATE log set a = a + 1; END;" -} - -ifcapable subquery { - set t232 {1 0 1} -} else { - set t232 {0 0 1} -} -do_test trigger2-3.2 { - execsql { - - INSERT INTO tbl VALUES(0, 0, 0, 0); -- 1 (ifcapable subquery) - SELECT * FROM log; - UPDATE log SET a = 0; - - INSERT INTO tbl VALUES(0, 0, 0, 0); -- 0 - SELECT * FROM log; - UPDATE log SET a = 0; - - INSERT INTO tbl VALUES(200, 0, 0, 0); -- 1 - SELECT * FROM log; - UPDATE log SET a = 0; - } -} $t232 -execsql { - DROP TABLE tbl; - DROP TABLE log; -} -integrity_check trigger2-3.3 - -# Simple cascaded trigger -execsql { - CREATE TABLE tblA(a, b); - CREATE TABLE tblB(a, b); - CREATE TABLE tblC(a, b); - - CREATE TRIGGER tr1 BEFORE INSERT ON tblA BEGIN - INSERT INTO tblB values(new.a, new.b); - END; - - CREATE TRIGGER tr2 BEFORE INSERT ON tblB BEGIN - INSERT INTO tblC values(new.a, new.b); - END; -} -do_test trigger2-4.1 { - execsql { - INSERT INTO tblA values(1, 2); - SELECT * FROM tblA; - SELECT * FROM tblB; - SELECT * FROM tblC; - } -} {1 2 1 2 1 2} -execsql { - DROP TABLE tblA; - DROP TABLE tblB; - DROP TABLE tblC; -} - -# Simple recursive trigger -execsql { - CREATE TABLE tbl(a, b, c); - CREATE TRIGGER tbl_trig BEFORE INSERT ON tbl - BEGIN - INSERT INTO tbl VALUES (new.a, new.b, new.c); - END; -} -do_test trigger2-4.2 { - execsql { - INSERT INTO tbl VALUES (1, 2, 3); - select * from tbl; - } -} {1 2 3 1 2 3} -execsql { - DROP TABLE tbl; -} - -# 5. -execsql { - CREATE TABLE tbl(a, b, c); - CREATE TRIGGER tbl_trig BEFORE INSERT ON tbl - BEGIN - INSERT INTO tbl VALUES (1, 2, 3); - INSERT INTO tbl VALUES (2, 2, 3); - UPDATE tbl set b = 10 WHERE a = 1; - DELETE FROM tbl WHERE a = 1; - DELETE FROM tbl; - END; -} -do_test trigger2-5 { - execsql { - INSERT INTO tbl VALUES(100, 200, 300); - } - db changes -} {1} -execsql { - DROP TABLE tbl; -} - -# Handling of ON CONFLICT by INSERT statements inside triggers -execsql { - CREATE TABLE tbl (a primary key, b, c); - CREATE TRIGGER ai_tbl AFTER INSERT ON tbl BEGIN - INSERT OR IGNORE INTO tbl values (new.a, 0, 0); - END; -} -do_test trigger2-6.1a { - execsql { - BEGIN; - INSERT INTO tbl values (1, 2, 3); - SELECT * from tbl; - } -} {1 2 3} -do_test trigger2-6.1b { - catchsql { - INSERT OR ABORT INTO tbl values (2, 2, 3); - } -} {1 {column a is not unique}} -do_test trigger2-6.1c { - execsql { - SELECT * from tbl; - } -} {1 2 3} -do_test trigger2-6.1d { - catchsql { - INSERT OR FAIL INTO tbl values (2, 2, 3); - } -} {1 {column a is not unique}} -do_test trigger2-6.1e { - execsql { - SELECT * from tbl; - } -} {1 2 3 2 2 3} -do_test trigger2-6.1f { - execsql { - INSERT OR REPLACE INTO tbl values (2, 2, 3); - SELECT * from tbl; - } -} {1 2 3 2 0 0} -do_test trigger2-6.1g { - catchsql { - INSERT OR ROLLBACK INTO tbl values (3, 2, 3); - } -} {1 {column a is not unique}} -do_test trigger2-6.1h { - execsql { - SELECT * from tbl; - } -} {} -execsql {DELETE FROM tbl} - - -# Handling of ON CONFLICT by UPDATE statements inside triggers -execsql { - INSERT INTO tbl values (4, 2, 3); - INSERT INTO tbl values (6, 3, 4); - CREATE TRIGGER au_tbl AFTER UPDATE ON tbl BEGIN - UPDATE OR IGNORE tbl SET a = new.a, c = 10; - END; -} -do_test trigger2-6.2a { - execsql { - BEGIN; - UPDATE tbl SET a = 1 WHERE a = 4; - SELECT * from tbl; - } -} {1 2 10 6 3 4} -do_test trigger2-6.2b { - catchsql { - UPDATE OR ABORT tbl SET a = 4 WHERE a = 1; - } -} {1 {column a is not unique}} -do_test trigger2-6.2c { - execsql { - SELECT * from tbl; - } -} {1 2 10 6 3 4} -do_test trigger2-6.2d { - catchsql { - UPDATE OR FAIL tbl SET a = 4 WHERE a = 1; - } -} {1 {column a is not unique}} -do_test trigger2-6.2e { - execsql { - SELECT * from tbl; - } -} {4 2 10 6 3 4} -do_test trigger2-6.2f.1 { - execsql { - UPDATE OR REPLACE tbl SET a = 1 WHERE a = 4; - SELECT * from tbl; - } -} {1 3 10} -do_test trigger2-6.2f.2 { - execsql { - INSERT INTO tbl VALUES (2, 3, 4); - SELECT * FROM tbl; - } -} {1 3 10 2 3 4} -do_test trigger2-6.2g { - catchsql { - UPDATE OR ROLLBACK tbl SET a = 4 WHERE a = 1; - } -} {1 {column a is not unique}} -do_test trigger2-6.2h { - execsql { - SELECT * from tbl; - } -} {4 2 3 6 3 4} -execsql { - DROP TABLE tbl; -} - -# 7. Triggers on views -ifcapable view { - -do_test trigger2-7.1 { - execsql { - CREATE TABLE ab(a, b); - CREATE TABLE cd(c, d); - INSERT INTO ab VALUES (1, 2); - INSERT INTO ab VALUES (0, 0); - INSERT INTO cd VALUES (3, 4); - - CREATE TABLE tlog(ii INTEGER PRIMARY KEY, - olda, oldb, oldc, oldd, newa, newb, newc, newd); - - CREATE VIEW abcd AS SELECT a, b, c, d FROM ab, cd; - - CREATE TRIGGER before_update INSTEAD OF UPDATE ON abcd BEGIN - INSERT INTO tlog VALUES(NULL, - old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d); - END; - CREATE TRIGGER after_update INSTEAD OF UPDATE ON abcd BEGIN - INSERT INTO tlog VALUES(NULL, - old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d); - END; - - CREATE TRIGGER before_delete INSTEAD OF DELETE ON abcd BEGIN - INSERT INTO tlog VALUES(NULL, - old.a, old.b, old.c, old.d, 0, 0, 0, 0); - END; - CREATE TRIGGER after_delete INSTEAD OF DELETE ON abcd BEGIN - INSERT INTO tlog VALUES(NULL, - old.a, old.b, old.c, old.d, 0, 0, 0, 0); - END; - - CREATE TRIGGER before_insert INSTEAD OF INSERT ON abcd BEGIN - INSERT INTO tlog VALUES(NULL, - 0, 0, 0, 0, new.a, new.b, new.c, new.d); - END; - CREATE TRIGGER after_insert INSTEAD OF INSERT ON abcd BEGIN - INSERT INTO tlog VALUES(NULL, - 0, 0, 0, 0, new.a, new.b, new.c, new.d); - END; - } -} {}; - -do_test trigger2-7.2 { - execsql { - UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1; - DELETE FROM abcd WHERE a = 1; - INSERT INTO abcd VALUES(10, 20, 30, 40); - SELECT * FROM tlog; - } -} [ list 1 1 2 3 4 100 25 3 4 \ - 2 1 2 3 4 100 25 3 4 \ - 3 1 2 3 4 0 0 0 0 \ - 4 1 2 3 4 0 0 0 0 \ - 5 0 0 0 0 10 20 30 40 \ - 6 0 0 0 0 10 20 30 40 ] - -do_test trigger2-7.3 { - execsql { - DELETE FROM tlog; - INSERT INTO abcd VALUES(10, 20, 30, 40); - UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1; - DELETE FROM abcd WHERE a = 1; - SELECT * FROM tlog; - } -} [ list \ - 1 0 0 0 0 10 20 30 40 \ - 2 0 0 0 0 10 20 30 40 \ - 3 1 2 3 4 100 25 3 4 \ - 4 1 2 3 4 100 25 3 4 \ - 5 1 2 3 4 0 0 0 0 \ - 6 1 2 3 4 0 0 0 0 \ -] -do_test trigger2-7.4 { - execsql { - DELETE FROM tlog; - DELETE FROM abcd WHERE a = 1; - INSERT INTO abcd VALUES(10, 20, 30, 40); - UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1; - SELECT * FROM tlog; - } -} [ list \ - 1 1 2 3 4 0 0 0 0 \ - 2 1 2 3 4 0 0 0 0 \ - 3 0 0 0 0 10 20 30 40 \ - 4 0 0 0 0 10 20 30 40 \ - 5 1 2 3 4 100 25 3 4 \ - 6 1 2 3 4 100 25 3 4 \ -] - -do_test trigger2-8.1 { - execsql { - CREATE TABLE t1(a,b,c); - INSERT INTO t1 VALUES(1,2,3); - CREATE VIEW v1 AS - SELECT a+b AS x, b+c AS y, a+c AS z FROM t1; - SELECT * FROM v1; - } -} {3 5 4} -do_test trigger2-8.2 { - execsql { - CREATE TABLE v1log(a,b,c,d,e,f); - CREATE TRIGGER r1 INSTEAD OF DELETE ON v1 BEGIN - INSERT INTO v1log VALUES(OLD.x,NULL,OLD.y,NULL,OLD.z,NULL); - END; - DELETE FROM v1 WHERE x=1; - SELECT * FROM v1log; - } -} {} -do_test trigger2-8.3 { - execsql { - DELETE FROM v1 WHERE x=3; - SELECT * FROM v1log; - } -} {3 {} 5 {} 4 {}} -do_test trigger2-8.4 { - execsql { - INSERT INTO t1 VALUES(4,5,6); - DELETE FROM v1log; - DELETE FROM v1 WHERE y=11; - SELECT * FROM v1log; - } -} {9 {} 11 {} 10 {}} -do_test trigger2-8.5 { - execsql { - CREATE TRIGGER r2 INSTEAD OF INSERT ON v1 BEGIN - INSERT INTO v1log VALUES(NULL,NEW.x,NULL,NEW.y,NULL,NEW.z); - END; - DELETE FROM v1log; - INSERT INTO v1 VALUES(1,2,3); - SELECT * FROM v1log; - } -} {{} 1 {} 2 {} 3} -do_test trigger2-8.6 { - execsql { - CREATE TRIGGER r3 INSTEAD OF UPDATE ON v1 BEGIN - INSERT INTO v1log VALUES(OLD.x,NEW.x,OLD.y,NEW.y,OLD.z,NEW.z); - END; - DELETE FROM v1log; - UPDATE v1 SET x=x+100, y=y+200, z=z+300; - SELECT * FROM v1log; - } -} {3 103 5 205 4 304 9 109 11 211 10 310} - -} ;# ifcapable view - -integrity_check trigger2-9.9 - -finish_test diff --git a/sqlite/test/trigger3.test b/sqlite/test/trigger3.test deleted file mode 100644 index d08ac28..0000000 --- a/sqlite/test/trigger3.test +++ /dev/null @@ -1,176 +0,0 @@ -# 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 tests the RAISE() function. -# - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -ifcapable {!trigger} { - finish_test - return -} - -# Test that we can cause ROLLBACK, FAIL and ABORT correctly -# catchsql { DROP TABLE tbl; } -catchsql { CREATE TABLE tbl (a, b, c) } - -execsql { - CREATE TRIGGER before_tbl_insert BEFORE INSERT ON tbl BEGIN SELECT CASE - WHEN (new.a = 4) THEN RAISE(IGNORE) END; - END; - - CREATE TRIGGER after_tbl_insert AFTER INSERT ON tbl BEGIN SELECT CASE - WHEN (new.a = 1) THEN RAISE(ABORT, 'Trigger abort') - WHEN (new.a = 2) THEN RAISE(FAIL, 'Trigger fail') - WHEN (new.a = 3) THEN RAISE(ROLLBACK, 'Trigger rollback') END; - END; -} -# ABORT -do_test trigger3-1.1 { - catchsql { - BEGIN; - INSERT INTO tbl VALUES (5, 5, 6); - INSERT INTO tbl VALUES (1, 5, 6); - } -} {1 {Trigger abort}} -do_test trigger3-1.2 { - execsql { - SELECT * FROM tbl; - ROLLBACK; - } -} {5 5 6} -do_test trigger3-1.3 { - execsql {SELECT * FROM tbl} -} {} - -# FAIL -do_test trigger3-2.1 { - catchsql { - BEGIN; - INSERT INTO tbl VALUES (5, 5, 6); - INSERT INTO tbl VALUES (2, 5, 6); - } -} {1 {Trigger fail}} -do_test trigger3-2.2 { - execsql { - SELECT * FROM tbl; - ROLLBACK; - } -} {5 5 6 2 5 6} -# ROLLBACK -do_test trigger3-3.1 { - catchsql { - BEGIN; - INSERT INTO tbl VALUES (5, 5, 6); - INSERT INTO tbl VALUES (3, 5, 6); - } -} {1 {Trigger rollback}} -do_test trigger3-3.2 { - execsql { - SELECT * FROM tbl; - } -} {} -# IGNORE -do_test trigger3-4.1 { - catchsql { - BEGIN; - INSERT INTO tbl VALUES (5, 5, 6); - INSERT INTO tbl VALUES (4, 5, 6); - } -} {0 {}} -do_test trigger3-4.2 { - execsql { - SELECT * FROM tbl; - ROLLBACK; - } -} {5 5 6} - -# Check that we can also do RAISE(IGNORE) for UPDATE and DELETE -execsql {DROP TABLE tbl;} -execsql {CREATE TABLE tbl (a, b, c);} -execsql {INSERT INTO tbl VALUES(1, 2, 3);} -execsql {INSERT INTO tbl VALUES(4, 5, 6);} -execsql { - CREATE TRIGGER before_tbl_update BEFORE UPDATE ON tbl BEGIN - SELECT CASE WHEN (old.a = 1) THEN RAISE(IGNORE) END; - END; - - CREATE TRIGGER before_tbl_delete BEFORE DELETE ON tbl BEGIN - SELECT CASE WHEN (old.a = 1) THEN RAISE(IGNORE) END; - END; -} -do_test trigger3-5.1 { - execsql { - UPDATE tbl SET c = 10; - SELECT * FROM tbl; - } -} {1 2 3 4 5 10} -do_test trigger3-5.2 { - execsql { - DELETE FROM tbl; - SELECT * FROM tbl; - } -} {1 2 3} - -# Check that RAISE(IGNORE) works correctly for nested triggers: -execsql {CREATE TABLE tbl2(a, b, c)} -execsql { - CREATE TRIGGER after_tbl2_insert AFTER INSERT ON tbl2 BEGIN - UPDATE tbl SET c = 10; - INSERT INTO tbl2 VALUES (new.a, new.b, new.c); - END; -} -do_test trigger3-6 { - execsql { - INSERT INTO tbl2 VALUES (1, 2, 3); - SELECT * FROM tbl2; - SELECT * FROM tbl; - } -} {1 2 3 1 2 3 1 2 3} - -# Check that things also work for view-triggers - -ifcapable view { - -execsql {CREATE VIEW tbl_view AS SELECT * FROM tbl} -execsql { - CREATE TRIGGER tbl_view_insert INSTEAD OF INSERT ON tbl_view BEGIN - SELECT CASE WHEN (new.a = 1) THEN RAISE(ROLLBACK, 'View rollback') - WHEN (new.a = 2) THEN RAISE(IGNORE) - WHEN (new.a = 3) THEN RAISE(ABORT, 'View abort') END; - END; -} - -do_test trigger3-7.1 { - catchsql { - INSERT INTO tbl_view VALUES(1, 2, 3); - } -} {1 {View rollback}} -do_test trigger3-7.2 { - catchsql { - INSERT INTO tbl_view VALUES(2, 2, 3); - } -} {0 {}} -do_test trigger3-7.3 { - catchsql { - INSERT INTO tbl_view VALUES(3, 2, 3); - } -} {1 {View abort}} - -} ;# ifcapable view - -integrity_check trigger3-8.1 - -catchsql { DROP TABLE tbl; } -catchsql { DROP TABLE tbl2; } -catchsql { DROP VIEW tbl_view; } - -finish_test diff --git a/sqlite/test/trigger4.test b/sqlite/test/trigger4.test deleted file mode 100644 index be88eb7..0000000 --- a/sqlite/test/trigger4.test +++ /dev/null @@ -1,133 +0,0 @@ -# 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 tests the triggers of views. -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If either views or triggers are disabled in this build, omit this file. -ifcapable {!trigger || !view} { - finish_test - return -} - -do_test trigger4-1.1 { - execsql { - create table test1(id integer primary key,a); - create table test2(id integer,b); - create view test as - select test1.id as id,a as a,b as b - from test1 join test2 on test2.id = test1.id; - create trigger I_test instead of insert on test - begin - insert into test1 (id,a) values (NEW.id,NEW.a); - insert into test2 (id,b) values (NEW.id,NEW.b); - end; - insert into test values(1,2,3); - select * from test1; - } -} {1 2} -do_test trigger4-1.2 { - execsql { - select * from test2; - } -} {1 3} -do_test trigger4-1.3 { - db close - sqlite3 db test.db - execsql { - insert into test values(4,5,6); - select * from test1; - } -} {1 2 4 5} -do_test trigger4-1.4 { - execsql { - select * from test2; - } -} {1 3 4 6} - -do_test trigger4-2.1 { - execsql { - create trigger U_test instead of update on test - begin - update test1 set a=NEW.a where id=NEW.id; - update test2 set b=NEW.b where id=NEW.id; - end; - update test set a=22 where id=1; - select * from test1; - } -} {1 22 4 5} -do_test trigger4-2.2 { - execsql { - select * from test2; - } -} {1 3 4 6} -do_test trigger4-2.3 { - db close - sqlite3 db test.db - execsql { - update test set b=66 where id=4; - select * from test1; - } -} {1 22 4 5} -do_test trigger4-2.4 { - execsql { - select * from test2; - } -} {1 3 4 66} - -do_test trigger4-3.1 { - catchsql { - drop table test2; - insert into test values(7,8,9); - } -} {1 {no such table: main.test2}} -do_test trigger4-3.2 { - db close - sqlite3 db test.db - catchsql { - insert into test values(7,8,9); - } -} {1 {no such table: main.test2}} -do_test trigger4-3.3 { - catchsql { - update test set a=222 where id=1; - } -} {1 {no such table: main.test2}} -do_test trigger4-3.4 { - execsql { - select * from test1; - } -} {1 22 4 5} -do_test trigger4-3.5 { - execsql { - create table test2(id,b); - insert into test values(7,8,9); - select * from test1; - } -} {1 22 4 5 7 8} -do_test trigger4-3.6 { - execsql { - select * from test2; - } -} {7 9} -do_test trigger4-3.7 { - db close - sqlite3 db test.db - execsql { - update test set b=99 where id=7; - select * from test2; - } -} {7 99} - -integrity_check trigger4-4.1 - -finish_test diff --git a/sqlite/test/trigger5.test b/sqlite/test/trigger5.test deleted file mode 100644 index 75c56b1..0000000 --- a/sqlite/test/trigger5.test +++ /dev/null @@ -1,43 +0,0 @@ -# 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 tests the triggers of views. -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -ifcapable {!trigger} { - finish_test - return -} - -# Ticket #844 -# -do_test trigger5-1.1 { - execsql { - CREATE TABLE Item( - a integer PRIMARY KEY NOT NULL , - b double NULL , - c int NOT NULL DEFAULT 0 - ); - CREATE TABLE Undo(UndoAction TEXT); - INSERT INTO Item VALUES (1,38205.60865,340); - CREATE TRIGGER trigItem_UNDO_AD AFTER DELETE ON Item FOR EACH ROW - BEGIN - INSERT INTO Undo SELECT 'INSERT INTO Item (a,b,c) VALUES (' - || coalesce(old.a,'NULL') || ',' || quote(old.b) || ',' || old.c || ');'; - END; - DELETE FROM Item WHERE a = 1; - SELECT * FROM Undo; - } -} {{INSERT INTO Item (a,b,c) VALUES (1,38205.60865,340);}} - -integrity_check trigger5-99.9 - -finish_test diff --git a/sqlite/test/trigger6.test b/sqlite/test/trigger6.test deleted file mode 100644 index 5fb71a5..0000000 --- a/sqlite/test/trigger6.test +++ /dev/null @@ -1,82 +0,0 @@ -# 2004 December 07 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# -# This file implements tests to make sure expression of an INSERT -# and UPDATE statement are only evaluated once. See ticket #980. -# If an expression uses a function that has side-effects or which -# is not deterministic (ex: random()) then we want to make sure -# that the same evaluation occurs for the actual INSERT/UPDATE and -# for the NEW.* fields of any triggers that fire. -# -# $Id: trigger6.test,v 1.1 2004/12/07 15:41:50 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -ifcapable {!trigger} { - finish_test - return -} - -do_test trigger6-1.1 { - execsql { - CREATE TABLE t1(x, y); - CREATE TABLE log(a, b, c); - CREATE TRIGGER r1 BEFORE INSERT ON t1 BEGIN - INSERT INTO log VALUES(1, new.x, new.y); - END; - CREATE TRIGGER r2 BEFORE UPDATE ON t1 BEGIN - INSERT INTO log VALUES(2, new.x, new.y); - END; - } - set ::trigger6_cnt 0 - proc trigger6_counter {args} { - incr ::trigger6_cnt - return $::trigger6_cnt - } - db function counter trigger6_counter - execsql { - INSERT INTO t1 VALUES(1,counter()); - SELECT * FROM t1; - } -} {1 1} -do_test trigger6-1.2 { - execsql { - SELECT * FROM log; - } -} {1 1 1} -do_test trigger6-1.3 { - execsql { - DELETE FROM t1; - DELETE FROM log; - INSERT INTO t1 VALUES(2,counter(2,3)+4); - SELECT * FROM t1; - } -} {2 6.0} -do_test trigger6-1.4 { - execsql { - SELECT * FROM log; - } -} {1 2 6.0} -do_test trigger6-1.5 { - execsql { - DELETE FROM log; - UPDATE t1 SET y=counter(5); - SELECT * FROM t1; - } -} {2 3} -do_test trigger6-1.6 { - execsql { - SELECT * FROM log; - } -} {2 2 3} - -finish_test diff --git a/sqlite/test/types.test b/sqlite/test/types.test deleted file mode 100644 index eda9e71..0000000 --- a/sqlite/test/types.test +++ /dev/null @@ -1,308 +0,0 @@ -# 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 implements regression tests for SQLite library. Specfically -# it tests that the different storage classes (integer, real, text etc.) -# all work correctly. -# -# $Id: types.test,v 1.14 2004/11/14 21:56:31 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Tests in this file are organized roughly as follows: -# -# types-1.*.*: Test that values are stored using the expected storage -# classes when various forms of literals are inserted into -# columns with different affinities. -# types-1.1.*: INSERT INTO
VALUES(...) -# types-1.2.*: INSERT INTO
SELECT... -# types-1.3.*: UPDATE
SET... -# -# types-2.*.*: Check that values can be stored and retrieving using the -# various storage classes. -# types-2.1.*: INTEGER -# types-2.2.*: REAL -# types-2.3.*: NULL -# types-2.4.*: TEXT -# types-2.5.*: Records with a few different storage classes. -# -# types-3.*: Test that the '=' operator respects manifest types. -# - -# Disable encryption on the database for this test. -db close -set DB [sqlite3 db test.db] -sqlite3_rekey $DB {} - -# Create a table with one column for each type of affinity -do_test types-1.1.0 { - execsql { - CREATE TABLE t1(i integer, n numeric, t text, o blob); - } -} {} - -# Each element of the following list represents one test case. -# -# The first value of each sub-list is an SQL literal. The following -# four value are the storage classes that would be used if the -# literal were inserted into a column with affinity INTEGER, NUMERIC, TEXT -# or NONE, respectively. -set values { - { 5.0 integer real text real } - { 5 integer integer text integer } - { '5.0' integer real text text } - { '-5.0' integer real text text } - { '-5.0' integer real text text } - { '5' integer integer text text } - { 'abc' text text text text } - { NULL null null null null } -} -ifcapable {bloblit} { - lappend values { X'00' blob blob blob blob } -} - -# This code tests that the storage classes specified above (in the $values -# table) are correctly assigned when values are inserted using a statement -# of the form: -# -# INSERT INTO
VALUE(); -# -set tnum 1 -foreach val $values { - set lit [lindex $val 0] - execsql "DELETE FROM t1;" - execsql "INSERT INTO t1 VALUES($lit, $lit, $lit, $lit);" - do_test types-1.1.$tnum { - execsql { - SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1; - } - } [lrange $val 1 end] - incr tnum -} - -# This code tests that the storage classes specified above (in the $values -# table) are correctly assigned when values are inserted using a statement -# of the form: -# -# INSERT INTO t1 SELECT .... -# -set tnum 1 -foreach val $values { - set lit [lindex $val 0] - execsql "DELETE FROM t1;" - execsql "INSERT INTO t1 SELECT $lit, $lit, $lit, $lit;" - do_test types-1.2.$tnum { - execsql { - SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1; - } - } [lrange $val 1 end] - incr tnum -} - -# This code tests that the storage classes specified above (in the $values -# table) are correctly assigned when values are inserted using a statement -# of the form: -# -# UPDATE
SET = ; -# -set tnum 1 -foreach val $values { - set lit [lindex $val 0] - execsql "UPDATE t1 SET i = $lit, n = $lit, t = $lit, o = $lit;" - do_test types-1.3.$tnum { - execsql { - SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1; - } - } [lrange $val 1 end] - incr tnum -} - -execsql { - DROP TABLE t1; -} - -# Open the table with root-page $rootpage at the btree -# level. Return a list that is the length of each record -# in the table, in the tables default scanning order. -proc record_sizes {rootpage} { - set bt [btree_open test.db 10 0] - set c [btree_cursor $bt $rootpage 0] - btree_first $c - while 1 { - lappend res [btree_payload_size $c] - if {[btree_next $c]} break - } - btree_close_cursor $c - btree_close $bt - set res -} - - -# Create a table and insert some 1-byte integers. Make sure they -# can be read back OK. These should be 3 byte records. -do_test types-2.1.1 { - execsql { - CREATE TABLE t1(a integer); - INSERT INTO t1 VALUES(0); - INSERT INTO t1 VALUES(120); - INSERT INTO t1 VALUES(-120); - } -} {} -do_test types-2.1.2 { - execsql { - SELECT a FROM t1; - } -} {0 120 -120} - -# Try some 2-byte integers (4 byte records) -do_test types-2.1.3 { - execsql { - INSERT INTO t1 VALUES(30000); - INSERT INTO t1 VALUES(-30000); - } -} {} -do_test types-2.1.4 { - execsql { - SELECT a FROM t1; - } -} {0 120 -120 30000 -30000} - -# 4-byte integers (6 byte records) -do_test types-2.1.5 { - execsql { - INSERT INTO t1 VALUES(2100000000); - INSERT INTO t1 VALUES(-2100000000); - } -} {} -do_test types-2.1.6 { - execsql { - SELECT a FROM t1; - } -} {0 120 -120 30000 -30000 2100000000 -2100000000} - -# 8-byte integers (10 byte records) -do_test types-2.1.7 { - execsql { - INSERT INTO t1 VALUES(9000000*1000000*1000000); - INSERT INTO t1 VALUES(-9000000*1000000*1000000); - } -} {} -do_test types-2.1.8 { - execsql { - SELECT a FROM t1; - } -} [list 0 120 -120 30000 -30000 2100000000 -2100000000 \ - 9000000000000000000 -9000000000000000000] - -# Check that all the record sizes are as we expected. -do_test types-2.1.9 { - set root [db eval {select rootpage from sqlite_master where name = 't1'}] - record_sizes $root -} {3 3 3 4 4 6 6 10 10} - -# Insert some reals. These should be 10 byte records. -do_test types-2.2.1 { - execsql { - CREATE TABLE t2(a float); - INSERT INTO t2 VALUES(0.0); - INSERT INTO t2 VALUES(12345.678); - INSERT INTO t2 VALUES(-12345.678); - } -} {} -do_test types-2.2.2 { - execsql { - SELECT a FROM t2; - } -} {0.0 12345.678 -12345.678} - -# Check that all the record sizes are as we expected. -do_test types-2.2.3 { - set root [db eval {select rootpage from sqlite_master where name = 't2'}] - record_sizes $root -} {10 10 10} - -# Insert a NULL. This should be a two byte record. -do_test types-2.3.1 { - execsql { - CREATE TABLE t3(a nullvalue); - INSERT INTO t3 VALUES(NULL); - } -} {} -do_test types-2.3.2 { - execsql { - SELECT a ISNULL FROM t3; - } -} {1} - -# Check that all the record sizes are as we expected. -do_test types-2.3.3 { - set root [db eval {select rootpage from sqlite_master where name = 't3'}] - record_sizes $root -} {2} - -# Insert a couple of strings. -do_test types-2.4.1 { - set string10 abcdefghij - set string500 [string repeat $string10 50] - set string500000 [string repeat $string10 50000] - - execsql " - CREATE TABLE t4(a string); - INSERT INTO t4 VALUES('$string10'); - INSERT INTO t4 VALUES('$string500'); - INSERT INTO t4 VALUES('$string500000'); - " -} {} -do_test types-2.4.2 { - execsql { - SELECT a FROM t4; - } -} [list $string10 $string500 $string500000] - -# Check that all the record sizes are as we expected. This is dependant on -# the database encoding. -if { $sqlite_options(utf16)==0 || [execsql {pragma encoding}] == "UTF-8" } { - do_test types-2.4.3 { - set root [db eval {select rootpage from sqlite_master where name = 't4'}] - record_sizes $root - } {12 503 500004} -} else { - do_test types-2.4.3 { - set root [db eval {select rootpage from sqlite_master where name = 't4'}] - record_sizes $root - } {22 1003 1000004} -} - -do_test types-2.5.1 { - execsql { - DROP TABLE t1; - DROP TABLE t2; - DROP TABLE t3; - DROP TABLE t4; - CREATE TABLE t1(a, b, c); - } -} {} -do_test types-2.5.2 { - set string10 abcdefghij - set string500 [string repeat $string10 50] - set string500000 [string repeat $string10 50000] - - execsql "INSERT INTO t1 VALUES(NULL, '$string10', 4000);" - execsql "INSERT INTO t1 VALUES('$string500', 4000, NULL);" - execsql "INSERT INTO t1 VALUES(4000, NULL, '$string500000');" -} {} -do_test types-2.5.3 { - execsql { - SELECT * FROM t1; - } -} [list {} $string10 4000 $string500 4000 {} 4000 {} $string500000] - -finish_test diff --git a/sqlite/test/types2.test b/sqlite/test/types2.test deleted file mode 100644 index 36dd489..0000000 --- a/sqlite/test/types2.test +++ /dev/null @@ -1,313 +0,0 @@ -# 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 implements regression tests for SQLite library. The focus -# of this file is testing the interaction of manifest types, type affinity -# and comparison expressions. -# -# $Id: types2.test,v 1.5 2005/01/21 03:12:16 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Tests in this file are organized roughly as follows: -# -# types2-1.*: The '=' operator in the absence of an index. -# types2-2.*: The '=' operator implemented using an index. -# types2-3.*: The '<' operator implemented using an index. -# types2-4.*: The '>' operator in the absence of an index. -# types2-5.*: The 'IN(x, y...)' operator in the absence of an index. -# types2-6.*: The 'IN(x, y...)' operator with an index. -# types2-7.*: The 'IN(SELECT...)' operator in the absence of an index. -# types2-8.*: The 'IN(SELECT...)' operator with an index. -# -# All tests test the operators using literals and columns, but no -# other types of expressions. All expressions except columns are -# handled similarly in the implementation. - -execsql { - CREATE TABLE t1( - i1 INTEGER, - i2 INTEGER, - n1 NUMERIC, - n2 NUMERIC, - t1 TEXT, - t2 TEXT, - o1 BLOB, - o2 BLOB - ); - INSERT INTO t1 VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -} - -proc test_bool {testname vars expr res} { - if { $vars != "" } { - execsql "UPDATE t1 SET $vars" - } - - foreach {t e r} [list $testname $expr $res] {} - - do_test $t.1 "execsql {SELECT $e FROM t1}" $r - do_test $t.2 "execsql {SELECT 1 FROM t1 WHERE $expr}" [expr $r?"1":""] - do_test $t.3 "execsql {SELECT 1 FROM t1 WHERE NOT ($e)}" [expr $r?"":"1"] -} - -# Compare literals against literals. This should always use a numeric -# comparison. -# -# Changed by ticket #805: Use no affinity for literal comparisons. -# -test_bool types2-1.1 "" {500 = 500.0} 1 -test_bool types2-1.2 "" {'500' = 500.0} 0 -test_bool types2-1.3 "" {500 = '500.0'} 0 -test_bool types2-1.4 "" {'500' = '500.0'} 0 - -# Compare literals against a column with TEXT affinity -test_bool types2-1.5 {t1=500} {500 = t1} 1 -test_bool types2-1.6 {t1=500} {'500' = t1} 1 -test_bool types2-1.7 {t1=500} {500.0 = t1} 0 -test_bool types2-1.8 {t1=500} {'500.0' = t1} 0 -test_bool types2-1.9 {t1='500'} {500 = t1} 1 -test_bool types2-1.10 {t1='500'} {'500' = t1} 1 -test_bool types2-1.11 {t1='500'} {500.0 = t1} 0 -test_bool types2-1.12 {t1='500'} {'500.0' = t1} 0 - -# Compare literals against a column with NUMERIC affinity -test_bool types2-1.13 {n1=500} {500 = n1} 1 -test_bool types2-1.14 {n1=500} {'500' = n1} 1 -test_bool types2-1.15 {n1=500} {500.0 = n1} 1 -test_bool types2-1.16 {n1=500} {'500.0' = n1} 1 -test_bool types2-1.17 {n1='500'} {500 = n1} 1 -test_bool types2-1.18 {n1='500'} {'500' = n1} 1 -test_bool types2-1.19 {n1='500'} {500.0 = n1} 1 -test_bool types2-1.20 {n1='500'} {'500.0' = n1} 1 - -# Compare literals against a column with affinity NONE -test_bool types2-1.21 {o1=500} {500 = o1} 1 -test_bool types2-1.22 {o1=500} {'500' = o1} 0 -test_bool types2-1.23 {o1=500} {500.0 = o1} 1 -test_bool types2-1.24 {o1=500} {'500.0' = o1} 0 -test_bool types2-1.25 {o1='500'} {500 = o1} 0 -test_bool types2-1.26 {o1='500'} {'500' = o1} 1 -test_bool types2-1.27 {o1='500'} {500.0 = o1} 0 -test_bool types2-1.28 {o1='500'} {'500.0' = o1} 0 - -set vals [list 10 10.0 '10' '10.0' 20 20.0 '20' '20.0' 30 30.0 '30' '30.0'] -# 1 2 3 4 5 6 7 8 9 10 11 12 - -execsql { - CREATE TABLE t2(i INTEGER, n NUMERIC, t TEXT, o XBLOBY); - CREATE INDEX t2i1 ON t2(i); - CREATE INDEX t2i2 ON t2(n); - CREATE INDEX t2i3 ON t2(t); - CREATE INDEX t2i4 ON t2(o); -} -foreach v $vals { - execsql "INSERT INTO t2 VALUES($v, $v, $v, $v);" -} - -proc test_boolset {testname where set} { - set ::tb_sql "SELECT rowid FROM t2 WHERE $where" - do_test $testname { - lsort -integer [execsql $::tb_sql] - } $set -} - -test_boolset types2-2.1 {i = 10} {1 2 3 4} -test_boolset types2-2.2 {i = 10.0} {1 2 3 4} -test_boolset types2-2.3 {i = '10'} {1 2 3 4} -test_boolset types2-2.4 {i = '10.0'} {1 2 3 4} - -test_boolset types2-2.5 {n = 20} {5 6 7 8} -test_boolset types2-2.6 {n = 20.0} {5 6 7 8} -test_boolset types2-2.7 {n = '20'} {5 6 7 8} -test_boolset types2-2.8 {n = '20.0'} {5 6 7 8} - -test_boolset types2-2.9 {t = 20} {5 7} -test_boolset types2-2.10 {t = 20.0} {6 8} -test_boolset types2-2.11 {t = '20'} {5 7} -test_boolset types2-2.12 {t = '20.0'} {6 8} - -test_boolset types2-2.10 {o = 30} {9 10} -test_boolset types2-2.11 {o = 30.0} {9 10} -test_boolset types2-2.12 {o = '30'} 11 -test_boolset types2-2.13 {o = '30.0'} 12 - -test_boolset types2-3.1 {i < 20} {1 2 3 4} -test_boolset types2-3.2 {i < 20.0} {1 2 3 4} -test_boolset types2-3.3 {i < '20'} {1 2 3 4} -test_boolset types2-3.4 {i < '20.0'} {1 2 3 4} - -test_boolset types2-3.1 {n < 20} {1 2 3 4} -test_boolset types2-3.2 {n < 20.0} {1 2 3 4} -test_boolset types2-3.3 {n < '20'} {1 2 3 4} -test_boolset types2-3.4 {n < '20.0'} {1 2 3 4} - -test_boolset types2-3.1 {t < 20} {1 2 3 4} -test_boolset types2-3.2 {t < 20.0} {1 2 3 4 5 7} -test_boolset types2-3.3 {t < '20'} {1 2 3 4} -test_boolset types2-3.4 {t < '20.0'} {1 2 3 4 5 7} - -test_boolset types2-3.1 {o < 20} {1 2} -test_boolset types2-3.2 {o < 20.0} {1 2} -test_boolset types2-3.3 {o < '20'} {1 2 3 4 5 6 9 10} -test_boolset types2-3.3 {o < '20.0'} {1 2 3 4 5 6 7 9 10} - -# Compare literals against literals (always a numeric comparison). -# Change (by ticket #805): No affinity in comparisons -test_bool types2-4.1 "" {500 > 60.0} 1 -test_bool types2-4.2 "" {'500' > 60.0} 1 -test_bool types2-4.3 "" {500 > '60.0'} 0 -test_bool types2-4.4 "" {'500' > '60.0'} 0 - -# Compare literals against a column with TEXT affinity -test_bool types2-4.5 {t1=500.0} {t1 > 500} 1 -test_bool types2-4.6 {t1=500.0} {t1 > '500' } 1 -test_bool types2-4.7 {t1=500.0} {t1 > 500.0 } 0 -test_bool types2-4.8 {t1=500.0} {t1 > '500.0' } 0 -test_bool types2-4.9 {t1='500.0'} {t1 > 500 } 1 -test_bool types2-4.10 {t1='500.0'} {t1 > '500' } 1 -test_bool types2-4.11 {t1='500.0'} {t1 > 500.0 } 0 -test_bool types2-4.12 {t1='500.0'} {t1 > '500.0' } 0 - -# Compare literals against a column with NUMERIC affinity -test_bool types2-4.13 {n1=400} {500 > n1} 1 -test_bool types2-4.14 {n1=400} {'500' > n1} 1 -test_bool types2-4.15 {n1=400} {500.0 > n1} 1 -test_bool types2-4.16 {n1=400} {'500.0' > n1} 1 -test_bool types2-4.17 {n1='400'} {500 > n1} 1 -test_bool types2-4.18 {n1='400'} {'500' > n1} 1 -test_bool types2-4.19 {n1='400'} {500.0 > n1} 1 -test_bool types2-4.20 {n1='400'} {'500.0' > n1} 1 - -# Compare literals against a column with affinity NONE -test_bool types2-4.21 {o1=500} {500 > o1} 0 -test_bool types2-4.22 {o1=500} {'500' > o1} 1 -test_bool types2-4.23 {o1=500} {500.0 > o1} 0 -test_bool types2-4.24 {o1=500} {'500.0' > o1} 1 -test_bool types2-4.25 {o1='500'} {500 > o1} 0 -test_bool types2-4.26 {o1='500'} {'500' > o1} 0 -test_bool types2-4.27 {o1='500'} {500.0 > o1} 0 -test_bool types2-4.28 {o1='500'} {'500.0' > o1} 1 - -ifcapable subquery { - # types2-5.* - The 'IN (x, y....)' operator with no index. - # - # Compare literals against literals (always a numeric comparison). - test_bool types2-5.1 {} {(NULL IN ('10.0', 20)) ISNULL} 1 - test_bool types2-5.2 {} {10 IN ('10.0', 20)} 1 - test_bool types2-5.3 {} {'10' IN ('10.0', 20)} 1 - test_bool types2-5.4 {} {10 IN (10.0, 20)} 1 - test_bool types2-5.5 {} {'10.0' IN (10, 20)} 1 - - # Compare literals against a column with TEXT affinity - test_bool types2-5.6 {t1='10.0'} {t1 IN (10.0, 20)} 1 - test_bool types2-5.7 {t1='10.0'} {t1 IN (10, 20)} 0 - test_bool types2-5.8 {t1='10'} {t1 IN (10.0, 20)} 0 - test_bool types2-5.9 {t1='10'} {t1 IN (20, '10.0')} 0 - test_bool types2-5.10 {t1=10} {t1 IN (20, '10')} 1 - - # Compare literals against a column with NUMERIC affinity - test_bool types2-5.11 {n1='10.0'} {n1 IN (10.0, 20)} 1 - test_bool types2-5.12 {n1='10.0'} {n1 IN (10, 20)} 1 - test_bool types2-5.13 {n1='10'} {n1 IN (10.0, 20)} 1 - test_bool types2-5.14 {n1='10'} {n1 IN (20, '10.0')} 1 - test_bool types2-5.15 {n1=10} {n1 IN (20, '10')} 1 - - # Compare literals against a column with affinity NONE - test_bool types2-5.16 {o1='10.0'} {o1 IN (10.0, 20)} 0 - test_bool types2-5.17 {o1='10.0'} {o1 IN (10, 20)} 0 - test_bool types2-5.18 {o1='10'} {o1 IN (10.0, 20)} 0 - test_bool types2-5.19 {o1='10'} {o1 IN (20, '10.0')} 0 - test_bool types2-5.20 {o1=10} {o1 IN (20, '10')} 0 - test_bool types2-5.21 {o1='10.0'} {o1 IN (10, 20, '10.0')} 1 - test_bool types2-5.22 {o1='10'} {o1 IN (10.0, 20, '10')} 1 - test_bool types2-5.23 {o1=10} {n1 IN (20, '10', 10)} 1 -} - -# Tests named types2-6.* use the same infrastructure as the types2-2.* -# tests. The contents of the vals array is repeated here for easy -# reference. -# -# set vals [list 10 10.0 '10' '10.0' 20 20.0 '20' '20.0' 30 30.0 '30' '30.0'] -# 1 2 3 4 5 6 7 8 9 10 11 12 - -ifcapable subquery { - test_boolset types2-6.1 {o IN ('10', 30)} {3 9 10} - test_boolset types2-6.2 {o IN (20.0, 30.0)} {5 6 9 10} - test_boolset types2-6.3 {t IN ('10', 30)} {1 3 9 11} - test_boolset types2-6.4 {t IN (20.0, 30.0)} {6 8 10 12} - test_boolset types2-6.5 {n IN ('10', 30)} {1 2 3 4 9 10 11 12} - test_boolset types2-6.6 {n IN (20.0, 30.0)} {5 6 7 8 9 10 11 12} - test_boolset types2-6.7 {i IN ('10', 30)} {1 2 3 4 9 10 11 12} - test_boolset types2-6.8 {i IN (20.0, 30.0)} {5 6 7 8 9 10 11 12} - - # Also test than IN(x, y, z) works on a rowid: - test_boolset types2-6.9 {rowid IN (1, 6, 10)} {1 6 10} -} - -# Tests types2-7.* concentrate on expressions of the form -# "x IN (SELECT...)" with no index. -execsql { - CREATE TABLE t3(i INTEGER, n NUMERIC, t TEXT, o BLOB); - INSERT INTO t3 VALUES(1, 1, 1, 1); - INSERT INTO t3 VALUES(2, 2, 2, 2); - INSERT INTO t3 VALUES(3, 3, 3, 3); - INSERT INTO t3 VALUES('1', '1', '1', '1'); - INSERT INTO t3 VALUES('1.0', '1.0', '1.0', '1.0'); -} - -ifcapable subquery { - test_bool types2-7.1 {i1=1} {i1 IN (SELECT i FROM t3)} 1 - test_bool types2-7.2 {i1='2.0'} {i1 IN (SELECT i FROM t3)} 1 - test_bool types2-7.3 {i1='2.0'} {i1 IN (SELECT n FROM t3)} 1 - test_bool types2-7.4 {i1='2.0'} {i1 IN (SELECT t FROM t3)} 1 - test_bool types2-7.5 {i1='2.0'} {i1 IN (SELECT o FROM t3)} 1 - - test_bool types2-7.6 {n1=1} {n1 IN (SELECT n FROM t3)} 1 - test_bool types2-7.7 {n1='2.0'} {n1 IN (SELECT i FROM t3)} 1 - test_bool types2-7.8 {n1='2.0'} {n1 IN (SELECT n FROM t3)} 1 - test_bool types2-7.9 {n1='2.0'} {n1 IN (SELECT t FROM t3)} 1 - test_bool types2-7.10 {n1='2.0'} {n1 IN (SELECT o FROM t3)} 1 - - test_bool types2-7.6 {t1=1} {t1 IN (SELECT t FROM t3)} 1 - test_bool types2-7.7 {t1='2.0'} {t1 IN (SELECT t FROM t3)} 0 - test_bool types2-7.8 {t1='2.0'} {t1 IN (SELECT n FROM t3)} 1 - test_bool types2-7.9 {t1='2.0'} {t1 IN (SELECT i FROM t3)} 1 - test_bool types2-7.10 {t1='2.0'} {t1 IN (SELECT o FROM t3)} 0 - test_bool types2-7.11 {t1='1.0'} {t1 IN (SELECT t FROM t3)} 1 - test_bool types2-7.12 {t1='1.0'} {t1 IN (SELECT o FROM t3)} 1 - - test_bool types2-7.13 {o1=2} {o1 IN (SELECT o FROM t3)} 1 - test_bool types2-7.14 {o1='2'} {o1 IN (SELECT o FROM t3)} 0 - test_bool types2-7.15 {o1='2'} {o1 IN (SELECT o||'' FROM t3)} 1 -} - -# set vals [list 10 10.0 '10' '10.0' 20 20.0 '20' '20.0' 30 30.0 '30' '30.0'] -# 1 2 3 4 5 6 7 8 9 10 11 12 -execsql { - CREATE TABLE t4(i INTEGER, n NUMERIC, t VARCHAR(20), o LARGE BLOB); - INSERT INTO t4 VALUES(10, 20, 20, 30); -} -ifcapable subquery { - test_boolset types2-8.1 {i IN (SELECT i FROM t4)} {1 2 3 4} - test_boolset types2-8.2 {n IN (SELECT i FROM t4)} {1 2 3 4} - test_boolset types2-8.3 {t IN (SELECT i FROM t4)} {1 2 3 4} - test_boolset types2-8.4 {o IN (SELECT i FROM t4)} {1 2 3 4} - test_boolset types2-8.5 {i IN (SELECT t FROM t4)} {5 6 7 8} - test_boolset types2-8.6 {n IN (SELECT t FROM t4)} {5 6 7 8} - test_boolset types2-8.7 {t IN (SELECT t FROM t4)} {5 7} - test_boolset types2-8.8 {o IN (SELECT t FROM t4)} {7} - test_boolset types2-8.9 {i IN (SELECT o FROM t4)} {9 10 11 12} - test_boolset types2-8.6 {n IN (SELECT o FROM t4)} {9 10 11 12} - test_boolset types2-8.7 {t IN (SELECT o FROM t4)} {9 11} - test_boolset types2-8.8 {o IN (SELECT o FROM t4)} {9 10} -} - -finish_test diff --git a/sqlite/test/update.test b/sqlite/test/update.test deleted file mode 100644 index d56c342..0000000 --- a/sqlite/test/update.test +++ /dev/null @@ -1,596 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the UPDATE statement. -# -# $Id: update.test,v 1.17 2005/01/21 03:12:16 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Try to update an non-existent table -# -do_test update-1.1 { - set v [catch {execsql {UPDATE test1 SET f2=5 WHERE f1<1}} msg] - lappend v $msg -} {1 {no such table: test1}} - -# Try to update a read-only table -# -do_test update-2.1 { - set v [catch \ - {execsql {UPDATE sqlite_master SET name='xyz' WHERE name='123'}} msg] - lappend v $msg -} {1 {table sqlite_master may not be modified}} - -# Create a table to work with -# -do_test update-3.1 { - execsql {CREATE TABLE test1(f1 int,f2 int)} - for {set i 1} {$i<=10} {incr i} { - set sql "INSERT INTO test1 VALUES($i,[expr {int(pow(2,$i))}])" - execsql $sql - } - execsql {SELECT * FROM test1 ORDER BY f1} -} {1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512 10 1024} - -# Unknown column name in an expression -# -do_test update-3.2 { - set v [catch {execsql {UPDATE test1 SET f1=f3*2 WHERE f2==32}} msg] - lappend v $msg -} {1 {no such column: f3}} -do_test update-3.3 { - set v [catch {execsql {UPDATE test1 SET f1=test2.f1*2 WHERE f2==32}} msg] - lappend v $msg -} {1 {no such column: test2.f1}} -do_test update-3.4 { - set v [catch {execsql {UPDATE test1 SET f3=f1*2 WHERE f2==32}} msg] - lappend v $msg -} {1 {no such column: f3}} - -# Actually do some updates -# -do_test update-3.5 { - execsql {UPDATE test1 SET f2=f2*3} -} {} -do_test update-3.6 { - execsql {SELECT * FROM test1 ORDER BY f1} -} {1 6 2 12 3 24 4 48 5 96 6 192 7 384 8 768 9 1536 10 3072} -do_test update-3.7 { - execsql {PRAGMA count_changes=on} - execsql {UPDATE test1 SET f2=f2/3 WHERE f1<=5} -} {5} -do_test update-3.8 { - execsql {SELECT * FROM test1 ORDER BY f1} -} {1 2 2 4 3 8 4 16 5 32 6 192 7 384 8 768 9 1536 10 3072} -do_test update-3.9 { - execsql {UPDATE test1 SET f2=f2/3 WHERE f1>5} -} {5} -do_test update-3.10 { - execsql {SELECT * FROM test1 ORDER BY f1} -} {1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512 10 1024} - -# Swap the values of f1 and f2 for all elements -# -do_test update-3.11 { - execsql {UPDATE test1 SET F2=f1, F1=f2} -} {10} -do_test update-3.12 { - execsql {SELECT * FROM test1 ORDER BY F1} -} {2 1 4 2 8 3 16 4 32 5 64 6 128 7 256 8 512 9 1024 10} -do_test update-3.13 { - execsql {PRAGMA count_changes=off} - execsql {UPDATE test1 SET F2=f1, F1=f2} -} {} -do_test update-3.14 { - execsql {SELECT * FROM test1 ORDER BY F1} -} {1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512 10 1024} - -# Create duplicate entries and make sure updating still -# works. -# -do_test update-4.0 { - execsql { - DELETE FROM test1 WHERE f1<=5; - INSERT INTO test1(f1,f2) VALUES(8,88); - INSERT INTO test1(f1,f2) VALUES(8,888); - INSERT INTO test1(f1,f2) VALUES(77,128); - INSERT INTO test1(f1,f2) VALUES(777,128); - } - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-4.1 { - execsql {UPDATE test1 SET f2=f2+1 WHERE f1==8} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 89 8 257 8 889 9 512 10 1024 77 128 777 128} -do_test update-4.2 { - execsql {UPDATE test1 SET f2=f2-1 WHERE f1==8 and f2>800} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 89 8 257 8 888 9 512 10 1024 77 128 777 128} -do_test update-4.3 { - execsql {UPDATE test1 SET f2=f2-1 WHERE f1==8 and f2<800} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-4.4 { - execsql {UPDATE test1 SET f1=f1+1 WHERE f2==128} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 8 88 8 128 8 256 8 888 9 512 10 1024 78 128 778 128} -do_test update-4.5 { - execsql {UPDATE test1 SET f1=f1-1 WHERE f1>100 and f2==128} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 8 88 8 128 8 256 8 888 9 512 10 1024 78 128 777 128} -do_test update-4.6 { - execsql { - PRAGMA count_changes=on; - UPDATE test1 SET f1=f1-1 WHERE f1<=100 and f2==128; - } -} {2} -do_test update-4.7 { - execsql { - PRAGMA count_changes=off; - SELECT * FROM test1 ORDER BY f1,f2 - } -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} - -# Repeat the previous sequence of tests with an index. -# -do_test update-5.0 { - execsql {CREATE INDEX idx1 ON test1(f1)} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-5.1 { - execsql {UPDATE test1 SET f2=f2+1 WHERE f1==8} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 89 8 257 8 889 9 512 10 1024 77 128 777 128} -do_test update-5.2 { - execsql {UPDATE test1 SET f2=f2-1 WHERE f1==8 and f2>800} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 89 8 257 8 888 9 512 10 1024 77 128 777 128} -do_test update-5.3 { - execsql {UPDATE test1 SET f2=f2-1 WHERE f1==8 and f2<800} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-5.4 { - execsql {UPDATE test1 SET f1=f1+1 WHERE f2==128} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 8 88 8 128 8 256 8 888 9 512 10 1024 78 128 778 128} -do_test update-5.4.1 { - execsql {SELECT * FROM test1 WHERE f1==78 ORDER BY f1,f2} -} {78 128} -do_test update-5.4.2 { - execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2} -} {778 128} -do_test update-5.4.3 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 128 8 256 8 888} -do_test update-5.5 { - execsql {UPDATE test1 SET f1=f1-1 WHERE f1>100 and f2==128} -} {} -do_test update-5.5.1 { - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 8 88 8 128 8 256 8 888 9 512 10 1024 78 128 777 128} -do_test update-5.5.2 { - execsql {SELECT * FROM test1 WHERE f1==78 ORDER BY f1,f2} -} {78 128} -do_test update-5.5.3 { - execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2} -} {} -do_test update-5.5.4 { - execsql {SELECT * FROM test1 WHERE f1==777 ORDER BY f1,f2} -} {777 128} -do_test update-5.5.5 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 128 8 256 8 888} -do_test update-5.6 { - execsql { - PRAGMA count_changes=on; - UPDATE test1 SET f1=f1-1 WHERE f1<=100 and f2==128; - } -} {2} -do_test update-5.6.1 { - execsql { - PRAGMA count_changes=off; - SELECT * FROM test1 ORDER BY f1,f2 - } -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-5.6.2 { - execsql {SELECT * FROM test1 WHERE f1==77 ORDER BY f1,f2} -} {77 128} -do_test update-5.6.3 { - execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2} -} {} -do_test update-5.6.4 { - execsql {SELECT * FROM test1 WHERE f1==777 ORDER BY f1,f2} -} {777 128} -do_test update-5.6.5 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 256 8 888} - -# Repeat the previous sequence of tests with a different index. -# -execsql {PRAGMA synchronous=FULL} -do_test update-6.0 { - execsql {DROP INDEX idx1} - execsql {CREATE INDEX idx1 ON test1(f2)} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-6.1 { - execsql {UPDATE test1 SET f2=f2+1 WHERE f1==8} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 89 8 257 8 889 9 512 10 1024 77 128 777 128} -do_test update-6.1.1 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 89 8 257 8 889} -do_test update-6.1.2 { - execsql {SELECT * FROM test1 WHERE f2==89 ORDER BY f1,f2} -} {8 89} -do_test update-6.1.3 { - execsql {SELECT * FROM test1 WHERE f1==88 ORDER BY f1,f2} -} {} -do_test update-6.2 { - execsql {UPDATE test1 SET f2=f2-1 WHERE f1==8 and f2>800} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 89 8 257 8 888 9 512 10 1024 77 128 777 128} -do_test update-6.3 { - execsql {UPDATE test1 SET f2=f2-1 WHERE f1==8 and f2<800} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-6.3.1 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 256 8 888} -do_test update-6.3.2 { - execsql {SELECT * FROM test1 WHERE f2==89 ORDER BY f1,f2} -} {} -do_test update-6.3.3 { - execsql {SELECT * FROM test1 WHERE f2==88 ORDER BY f1,f2} -} {8 88} -do_test update-6.4 { - execsql {UPDATE test1 SET f1=f1+1 WHERE f2==128} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 8 88 8 128 8 256 8 888 9 512 10 1024 78 128 778 128} -do_test update-6.4.1 { - execsql {SELECT * FROM test1 WHERE f1==78 ORDER BY f1,f2} -} {78 128} -do_test update-6.4.2 { - execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2} -} {778 128} -do_test update-6.4.3 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 128 8 256 8 888} -do_test update-6.5 { - execsql {UPDATE test1 SET f1=f1-1 WHERE f1>100 and f2==128} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 8 88 8 128 8 256 8 888 9 512 10 1024 78 128 777 128} -do_test update-6.5.1 { - execsql {SELECT * FROM test1 WHERE f1==78 ORDER BY f1,f2} -} {78 128} -do_test update-6.5.2 { - execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2} -} {} -do_test update-6.5.3 { - execsql {SELECT * FROM test1 WHERE f1==777 ORDER BY f1,f2} -} {777 128} -do_test update-6.5.4 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 128 8 256 8 888} -do_test update-6.6 { - execsql {UPDATE test1 SET f1=f1-1 WHERE f1<=100 and f2==128} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-6.6.1 { - execsql {SELECT * FROM test1 WHERE f1==77 ORDER BY f1,f2} -} {77 128} -do_test update-6.6.2 { - execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2} -} {} -do_test update-6.6.3 { - execsql {SELECT * FROM test1 WHERE f1==777 ORDER BY f1,f2} -} {777 128} -do_test update-6.6.4 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 256 8 888} - -# Repeat the previous sequence of tests with multiple -# indices -# -do_test update-7.0 { - execsql {CREATE INDEX idx2 ON test1(f2)} - execsql {CREATE INDEX idx3 ON test1(f1,f2)} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-7.1 { - execsql {UPDATE test1 SET f2=f2+1 WHERE f1==8} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 89 8 257 8 889 9 512 10 1024 77 128 777 128} -do_test update-7.1.1 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 89 8 257 8 889} -do_test update-7.1.2 { - execsql {SELECT * FROM test1 WHERE f2==89 ORDER BY f1,f2} -} {8 89} -do_test update-7.1.3 { - execsql {SELECT * FROM test1 WHERE f1==88 ORDER BY f1,f2} -} {} -do_test update-7.2 { - execsql {UPDATE test1 SET f2=f2-1 WHERE f1==8 and f2>800} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 89 8 257 8 888 9 512 10 1024 77 128 777 128} -do_test update-7.3 { - # explain {UPDATE test1 SET f2=f2-1 WHERE f1==8 and F2<300} - execsql {UPDATE test1 SET f2=f2-1 WHERE f1==8 and f2<800} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-7.3.1 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 256 8 888} -do_test update-7.3.2 { - execsql {SELECT * FROM test1 WHERE f2==89 ORDER BY f1,f2} -} {} -do_test update-7.3.3 { - execsql {SELECT * FROM test1 WHERE f2==88 ORDER BY f1,f2} -} {8 88} -do_test update-7.4 { - execsql {UPDATE test1 SET f1=f1+1 WHERE f2==128} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 8 88 8 128 8 256 8 888 9 512 10 1024 78 128 778 128} -do_test update-7.4.1 { - execsql {SELECT * FROM test1 WHERE f1==78 ORDER BY f1,f2} -} {78 128} -do_test update-7.4.2 { - execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2} -} {778 128} -do_test update-7.4.3 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 128 8 256 8 888} -do_test update-7.5 { - execsql {UPDATE test1 SET f1=f1-1 WHERE f1>100 and f2==128} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 8 88 8 128 8 256 8 888 9 512 10 1024 78 128 777 128} -do_test update-7.5.1 { - execsql {SELECT * FROM test1 WHERE f1==78 ORDER BY f1,f2} -} {78 128} -do_test update-7.5.2 { - execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2} -} {} -do_test update-7.5.3 { - execsql {SELECT * FROM test1 WHERE f1==777 ORDER BY f1,f2} -} {777 128} -do_test update-7.5.4 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 128 8 256 8 888} -do_test update-7.6 { - execsql {UPDATE test1 SET f1=f1-1 WHERE f1<=100 and f2==128} - execsql {SELECT * FROM test1 ORDER BY f1,f2} -} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128} -do_test update-7.6.1 { - execsql {SELECT * FROM test1 WHERE f1==77 ORDER BY f1,f2} -} {77 128} -do_test update-7.6.2 { - execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2} -} {} -do_test update-7.6.3 { - execsql {SELECT * FROM test1 WHERE f1==777 ORDER BY f1,f2} -} {777 128} -do_test update-7.6.4 { - execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2} -} {8 88 8 256 8 888} - -# Error messages -# -do_test update-9.1 { - set v [catch {execsql { - UPDATE test1 SET x=11 WHERE f1=1025 - }} msg] - lappend v $msg -} {1 {no such column: x}} -do_test update-9.2 { - set v [catch {execsql { - UPDATE test1 SET f1=x(11) WHERE f1=1025 - }} msg] - lappend v $msg -} {1 {no such function: x}} -do_test update-9.3 { - set v [catch {execsql { - UPDATE test1 SET f1=11 WHERE x=1025 - }} msg] - lappend v $msg -} {1 {no such column: x}} -do_test update-9.4 { - set v [catch {execsql { - UPDATE test1 SET f1=11 WHERE x(f1)=1025 - }} msg] - lappend v $msg -} {1 {no such function: x}} - -# Try doing updates on a unique column where the value does not -# really change. -# -do_test update-10.1 { - execsql { - DROP TABLE test1; - CREATE TABLE t1( - a integer primary key, - b UNIQUE, - c, d, - e, f, - UNIQUE(c,d) - ); - INSERT INTO t1 VALUES(1,2,3,4,5,6); - INSERT INTO t1 VALUES(2,3,4,4,6,7); - SELECT * FROM t1 - } -} {1 2 3 4 5 6 2 3 4 4 6 7} -do_test update-10.2 { - catchsql { - UPDATE t1 SET a=1, e=9 WHERE f=6; - SELECT * FROM t1; - } -} {0 {1 2 3 4 9 6 2 3 4 4 6 7}} -do_test update-10.3 { - catchsql { - UPDATE t1 SET a=1, e=10 WHERE f=7; - SELECT * FROM t1; - } -} {1 {PRIMARY KEY must be unique}} -do_test update-10.4 { - catchsql { - SELECT * FROM t1; - } -} {0 {1 2 3 4 9 6 2 3 4 4 6 7}} -do_test update-10.5 { - catchsql { - UPDATE t1 SET b=2, e=11 WHERE f=6; - SELECT * FROM t1; - } -} {0 {1 2 3 4 11 6 2 3 4 4 6 7}} -do_test update-10.6 { - catchsql { - UPDATE t1 SET b=2, e=12 WHERE f=7; - SELECT * FROM t1; - } -} {1 {column b is not unique}} -do_test update-10.7 { - catchsql { - SELECT * FROM t1; - } -} {0 {1 2 3 4 11 6 2 3 4 4 6 7}} -do_test update-10.8 { - catchsql { - UPDATE t1 SET c=3, d=4, e=13 WHERE f=6; - SELECT * FROM t1; - } -} {0 {1 2 3 4 13 6 2 3 4 4 6 7}} -do_test update-10.9 { - catchsql { - UPDATE t1 SET c=3, d=4, e=14 WHERE f=7; - SELECT * FROM t1; - } -} {1 {columns c, d are not unique}} -do_test update-10.10 { - catchsql { - SELECT * FROM t1; - } -} {0 {1 2 3 4 13 6 2 3 4 4 6 7}} - -# Make sure we can handle a subquery in the where clause. -# -ifcapable subquery { - do_test update-11.1 { - execsql { - UPDATE t1 SET e=e+1 WHERE b IN (SELECT b FROM t1); - SELECT b,e FROM t1; - } - } {2 14 3 7} - do_test update-11.2 { - execsql { - UPDATE t1 SET e=e+1 WHERE a IN (SELECT a FROM t1); - SELECT a,e FROM t1; - } - } {1 15 2 8} -} - -integrity_check update-12.1 - -# Ticket 602. Updates should occur in the same order as the records -# were discovered in the WHERE clause. -# -do_test update-13.1 { - execsql { - BEGIN; - CREATE TABLE t2(a); - INSERT INTO t2 VALUES(1); - INSERT INTO t2 VALUES(2); - INSERT INTO t2 SELECT a+2 FROM t2; - INSERT INTO t2 SELECT a+4 FROM t2; - INSERT INTO t2 SELECT a+8 FROM t2; - INSERT INTO t2 SELECT a+16 FROM t2; - INSERT INTO t2 SELECT a+32 FROM t2; - INSERT INTO t2 SELECT a+64 FROM t2; - INSERT INTO t2 SELECT a+128 FROM t2; - INSERT INTO t2 SELECT a+256 FROM t2; - INSERT INTO t2 SELECT a+512 FROM t2; - INSERT INTO t2 SELECT a+1024 FROM t2; - COMMIT; - SELECT count(*) FROM t2; - } -} {2048} -do_test update-13.2 { - execsql { - SELECT count(*) FROM t2 WHERE a=rowid; - } -} {2048} -do_test update-13.3 { - execsql { - UPDATE t2 SET rowid=rowid-1; - SELECT count(*) FROM t2 WHERE a=rowid+1; - } -} {2048} -do_test update-13.3 { - execsql { - UPDATE t2 SET rowid=rowid+10000; - UPDATE t2 SET rowid=rowid-9999; - SELECT count(*) FROM t2 WHERE a=rowid; - } -} {2048} -do_test update-13.4 { - execsql { - BEGIN; - INSERT INTO t2 SELECT a+2048 FROM t2; - INSERT INTO t2 SELECT a+4096 FROM t2; - INSERT INTO t2 SELECT a+8192 FROM t2; - SELECT count(*) FROM t2 WHERE a=rowid; - COMMIT; - } -} 16384 -do_test update-13.5 { - execsql { - UPDATE t2 SET rowid=rowid-1; - SELECT count(*) FROM t2 WHERE a=rowid+1; - } -} 16384 - -integrity_check update-13.6 - -ifcapable {trigger} { -# Test for proper detection of malformed WHEN clauses on UPDATE triggers. -# -do_test update-14.1 { - execsql { - CREATE TABLE t3(a,b,c); - CREATE TRIGGER t3r1 BEFORE UPDATE on t3 WHEN nosuchcol BEGIN - SELECT 'illegal WHEN clause'; - END; - } -} {} -do_test update-14.2 { - catchsql { - UPDATE t3 SET a=1; - } -} {1 {no such column: nosuchcol}} -do_test update-14.3 { - execsql { - CREATE TABLE t4(a,b,c); - CREATE TRIGGER t4r1 AFTER UPDATE on t4 WHEN nosuchcol BEGIN - SELECT 'illegal WHEN clause'; - END; - } -} {} -do_test update-14.4 { - catchsql { - UPDATE t4 SET a=1; - } -} {1 {no such column: nosuchcol}} - -} ;# ifcapable {trigger} - - -finish_test diff --git a/sqlite/test/vacuum.test b/sqlite/test/vacuum.test deleted file mode 100644 index 5ba8517..0000000 --- a/sqlite/test/vacuum.test +++ /dev/null @@ -1,352 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the VACUUM statement. -# -# $Id: vacuum.test,v 1.34 2005/02/12 00:19:30 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If the VACUUM statement is disabled in the current build, skip all -# the tests in this file. -# -ifcapable {!vacuum} { - finish_test - return -} -if $AUTOVACUUM { - finish_test - return -} - -set fcnt 1 -proc cksum {{db db}} { - set sql "SELECT name, type, sql FROM sqlite_master ORDER BY name, type" - set txt [$db eval $sql]\n - set sql "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name" - foreach tbl [$db eval $sql] { - append txt [$db eval "SELECT * FROM $tbl"]\n - } - foreach prag {default_cache_size} { - append txt $prag-[$db eval "PRAGMA $prag"]\n - } - if 1 { - global fcnt - set fd [open dump$fcnt.txt w] - puts -nonewline $fd $txt - close $fd - incr fcnt - } - set cksum [string length $txt]-[md5 $txt] - # puts $cksum-[file size test.db] - return $cksum -} -do_test vacuum-1.1 { - execsql { - BEGIN; - CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); - INSERT INTO t1 VALUES(NULL,randstr(10,100),randstr(5,50)); - INSERT INTO t1 VALUES(123456,randstr(10,100),randstr(5,50)); - INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; - INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; - CREATE INDEX i1 ON t1(b,c); - CREATE UNIQUE INDEX i2 ON t1(c,a); - CREATE TABLE t2 AS SELECT * FROM t1; - COMMIT; - DROP TABLE t2; - } - set ::size1 [file size test.db] - set ::cksum [cksum] - expr {$::cksum!=""} -} {1} -do_test vacuum-1.2 { - execsql { - VACUUM; - } - cksum -} $cksum -ifcapable vacuum { - do_test vacuum-1.3 { - expr {[file size test.db]<$::size1} - } {1} -} -do_test vacuum-1.4 { - set sql_script { - BEGIN; - CREATE TABLE t2 AS SELECT * FROM t1; - CREATE TABLE t3 AS SELECT * FROM t1; - CREATE VIEW v1 AS SELECT b, c FROM t3; - CREATE TRIGGER r1 AFTER DELETE ON t2 BEGIN SELECT 1; END; - COMMIT; - DROP TABLE t2; - } - # If the library was compiled to omit view support, comment out the - # create view in the script $sql_script before executing it. Similarly, - # if triggers are not supported, comment out the trigger definition. - ifcapable !view { - regsub {CREATE VIEW} $sql_script {-- CREATE VIEW} sql_script - } - ifcapable !trigger { - regsub {CREATE TRIGGER} $sql_script {-- CREATE TRIGGER} sql_script - } - execsql $sql_script - set ::size1 [file size test.db] - set ::cksum [cksum] - expr {$::cksum!=""} -} {1} -do_test vacuum-1.5 { - execsql { - VACUUM; - } - cksum -} $cksum - -ifcapable vacuum { - do_test vacuum-1.6 { - expr {[file size test.db]<$::size1} - } {1} -} -ifcapable vacuum { - do_test vacuum-2.1 { - catchsql { - BEGIN; - VACUUM; - COMMIT; - } - } {1 {cannot VACUUM from within a transaction}} - catch {db eval COMMIT} -} -do_test vacuum-2.2 { - sqlite3 db2 test.db - execsql { - BEGIN; - CREATE TABLE t4 AS SELECT * FROM t1; - CREATE TABLE t5 AS SELECT * FROM t1; - COMMIT; - DROP TABLE t4; - DROP TABLE t5; - } db2 - set ::cksum [cksum db2] - catchsql { - VACUUM - } -} {0 {}} -do_test vacuum-2.3 { - cksum -} $cksum -do_test vacuum-2.4 { - catch {db2 eval {SELECT count(*) FROM sqlite_master}} - cksum db2 -} $cksum - -# Make sure the schema cookie is incremented by vacuum. -# -do_test vacuum-2.5 { - execsql { - BEGIN; - CREATE TABLE t6 AS SELECT * FROM t1; - CREATE TABLE t7 AS SELECT * FROM t1; - COMMIT; - } - sqlite3 db3 test.db - execsql { - SELECT * FROM t7 LIMIT 1 - } db3 - execsql { - VACUUM; - } - execsql { - INSERT INTO t7 VALUES(1234567890,'hello','world'); - } db3 - execsql { - SELECT * FROM t7 WHERE a=1234567890 - } -} {1234567890 hello world} -integrity_check vacuum-2.6 -do_test vacuum-2.7 { - execsql { - SELECT * FROM t7 WHERE a=1234567890 - } db3 -} {1234567890 hello world} -do_test vacuum-2.8 { - execsql { - INSERT INTO t7 SELECT * FROM t6; - SELECT count(*) FROM t7; - } -} 513 -integrity_check vacuum-2.9 -do_test vacuum-2.10 { - execsql { - DELETE FROM t7; - SELECT count(*) FROM t7; - } db3 -} 0 -integrity_check vacuum-2.11 -db3 close - - -# Ticket #427. Make sure VACUUM works when the EMPTY_RESULT_CALLBACKS -# pragma is turned on. -# -do_test vacuum-3.1 { - db close - db2 close - file delete test.db - sqlite3 db test.db - execsql { - PRAGMA empty_result_callbacks=on; - VACUUM; - } -} {} - -# Ticket #464. Make sure VACUUM works with the sqlite3_prepare() API. -# -do_test vacuum-4.1 { - db close - set DB [sqlite3 db test.db] - set VM [sqlite3_prepare $DB {VACUUM} -1 TAIL] - sqlite3_step $VM -} {SQLITE_DONE} -do_test vacuum-4.2 { - sqlite3_finalize $VM -} SQLITE_OK - -# Ticket #515. VACUUM after deleting and recreating the table that -# a view refers to. Omit this test if the library is not view-enabled. -# -ifcapable view { -do_test vacuum-5.1 { - db close - file delete -force test.db - sqlite3 db test.db - catchsql { - CREATE TABLE Test (TestID int primary key); - INSERT INTO Test VALUES (NULL); - CREATE VIEW viewTest AS SELECT * FROM Test; - - BEGIN; - CREATE TEMP TABLE tempTest (TestID int primary key, Test2 int NULL); - INSERT INTO tempTest SELECT TestID, 1 FROM Test; - DROP TABLE Test; - CREATE TABLE Test(TestID int primary key, Test2 int NULL); - INSERT INTO Test SELECT * FROM tempTest; - COMMIT; - VACUUM; - } -} {0 {}} -do_test vacuum-5.2 { - catchsql { - VACUUM; - } -} {0 {}} -} ;# ifcapable view - -# Ensure vacuum works with complicated tables names. -do_test vacuum-6.1 { - execsql { - CREATE TABLE "abc abc"(a, b, c); - INSERT INTO "abc abc" VALUES(1, 2, 3); - VACUUM; - } -} {} -do_test vacuum-6.2 { - execsql { - select * from "abc abc"; - } -} {1 2 3} - -# Also ensure that blobs survive a vacuum. -ifcapable {bloblit} { - do_test vacuum-6.3 { - execsql { - DELETE FROM "abc abc"; - INSERT INTO "abc abc" VALUES(X'00112233', NULL, NULL); - VACUUM; - } - } {} - do_test vacuum-6.4 { - execsql { - select count(*) from "abc abc" WHERE a = X'00112233'; - } - } {1} -} - -# Check what happens when an in-memory database is vacuumed. The -# [file delete] command covers us in case the library was compiled -# without in-memory database support. -# -file delete -force :memory: -do_test vacuum-7.0 { - sqlite3 db2 :memory: - execsql { - CREATE TABLE t1(t); - VACUUM; - } db2 -} {} -db2 close - -# Ticket #873. VACUUM a database that has ' in its name. -# -do_test vacuum-8.1 { - file delete -force a'z.db - file delete -force a'z.db-journal - sqlite3 db2 a'z.db - execsql { - CREATE TABLE t1(t); - VACUUM; - } db2 -} {} -db2 close - -# Ticket #1095: Vacuum a table that uses AUTOINCREMENT -# -ifcapable {autoinc} { - do_test vacuum-9.1 { - execsql { - DROP TABLE 'abc abc'; - CREATE TABLE autoinc(a INTEGER PRIMARY KEY AUTOINCREMENT, b); - INSERT INTO autoinc(b) VALUES('hi'); - INSERT INTO autoinc(b) VALUES('there'); - DELETE FROM autoinc; - } - set ::cksum [cksum] - expr {$::cksum!=""} - } {1} - do_test vacuum-9.2 { - execsql { - VACUUM; - } - cksum - } $::cksum - do_test vacuum-9.3 { - execsql { - INSERT INTO autoinc(b) VALUES('one'); - INSERT INTO autoinc(b) VALUES('two'); - } - set ::cksum [cksum] - expr {$::cksum!=""} - } {1} - do_test vacuum-9.4 { - execsql { - VACUUM; - } - cksum - } $::cksum -} - - -finish_test diff --git a/sqlite/test/view.test b/sqlite/test/view.test deleted file mode 100644 index cbcbe5c..0000000 --- a/sqlite/test/view.test +++ /dev/null @@ -1,443 +0,0 @@ -# 2002 February 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 implements regression tests for SQLite library. The -# focus of this file is testing VIEW statements. -# -# $Id: view.test,v 1.24 2005/01/30 11:11:44 danielk1977 Exp $ -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Omit this entire file if the library is not configured with views enabled. -ifcapable !view { - finish_test - return -} - -do_test view-1.0 { - execsql { - CREATE TABLE t1(a,b,c); - INSERT INTO t1 VALUES(1,2,3); - INSERT INTO t1 VALUES(4,5,6); - INSERT INTO t1 VALUES(7,8,9); - SELECT * FROM t1; - } -} {1 2 3 4 5 6 7 8 9} - -do_test view-1.1 { - execsql { - BEGIN; - CREATE VIEW v1 AS SELECT a,b FROM t1; - SELECT * FROM v1 ORDER BY a; - } -} {1 2 4 5 7 8} -do_test view-1.2 { - catchsql { - ROLLBACK; - SELECT * FROM v1 ORDER BY a; - } -} {1 {no such table: v1}} -do_test view-1.3 { - execsql { - CREATE VIEW v1 AS SELECT a,b FROM t1; - SELECT * FROM v1 ORDER BY a; - } -} {1 2 4 5 7 8} -do_test view-1.3.1 { - db close - sqlite3 db test.db - execsql { - SELECT * FROM v1 ORDER BY a; - } -} {1 2 4 5 7 8} -do_test view-1.4 { - catchsql { - DROP VIEW v1; - SELECT * FROM v1 ORDER BY a; - } -} {1 {no such table: v1}} -do_test view-1.5 { - execsql { - CREATE VIEW v1 AS SELECT a,b FROM t1; - SELECT * FROM v1 ORDER BY a; - } -} {1 2 4 5 7 8} -do_test view-1.6 { - catchsql { - DROP TABLE t1; - SELECT * FROM v1 ORDER BY a; - } -} {1 {no such table: main.t1}} -do_test view-1.7 { - execsql { - CREATE TABLE t1(x,a,b,c); - INSERT INTO t1 VALUES(1,2,3,4); - INSERT INTO t1 VALUES(4,5,6,7); - INSERT INTO t1 VALUES(7,8,9,10); - SELECT * FROM v1 ORDER BY a; - } -} {2 3 5 6 8 9} -do_test view-1.8 { - db close - sqlite3 db test.db - execsql { - SELECT * FROM v1 ORDER BY a; - } -} {2 3 5 6 8 9} - -do_test view-2.1 { - execsql { - CREATE VIEW v2 AS SELECT * FROM t1 WHERE a>5 - }; # No semicolon - execsql2 { - SELECT * FROM v2; - } -} {x 7 a 8 b 9 c 10} -do_test view-2.2 { - catchsql { - INSERT INTO v2 VALUES(1,2,3,4); - } -} {1 {cannot modify v2 because it is a view}} -do_test view-2.3 { - catchsql { - UPDATE v2 SET a=10 WHERE a=5; - } -} {1 {cannot modify v2 because it is a view}} -do_test view-2.4 { - catchsql { - DELETE FROM v2; - } -} {1 {cannot modify v2 because it is a view}} -do_test view-2.5 { - execsql { - INSERT INTO t1 VALUES(11,12,13,14); - SELECT * FROM v2 ORDER BY x; - } -} {7 8 9 10 11 12 13 14} -do_test view-2.6 { - execsql { - SELECT x FROM v2 WHERE a>10 - } -} {11} - -# Test that column name of views are generated correctly. -# -do_test view-3.1 { - execsql2 { - SELECT * FROM v1 LIMIT 1 - } -} {a 2 b 3} -do_test view-3.2 { - execsql2 { - SELECT * FROM v2 LIMIT 1 - } -} {x 7 a 8 b 9 c 10} -do_test view-3.3 { - execsql2 { - DROP VIEW v1; - CREATE VIEW v1 AS SELECT a AS 'xyz', b+c AS 'pqr', c-b FROM t1; - SELECT * FROM v1 LIMIT 1 - } -} {xyz 2 pqr 7 c-b 1} - -ifcapable compound { -do_test view-3.4 { - execsql2 { - CREATE VIEW v3 AS SELECT a FROM t1 UNION SELECT b FROM t1 ORDER BY b; - SELECT * FROM v3 LIMIT 4; - } -} {b 2 b 3 b 5 b 6} -do_test view-3.5 { - execsql2 { - CREATE VIEW v4 AS - SELECT a, b FROM t1 - UNION - SELECT b AS 'x', a AS 'y' FROM t1 - ORDER BY x, y; - SELECT y FROM v4 ORDER BY y LIMIT 4; - } -} {y 2 y 3 y 5 y 6} -} ;# ifcapable compound - - -do_test view-4.1 { - catchsql { - DROP VIEW t1; - } -} {1 {use DROP TABLE to delete table t1}} -do_test view-4.2 { - execsql { - SELECT 1 FROM t1 LIMIT 1; - } -} 1 -do_test view-4.3 { - catchsql { - DROP TABLE v1; - } -} {1 {use DROP VIEW to delete view v1}} -do_test view-4.4 { - execsql { - SELECT 1 FROM v1 LIMIT 1; - } -} {1} -do_test view-4.5 { - catchsql { - CREATE INDEX i1v1 ON v1(xyz); - } -} {1 {views may not be indexed}} - -do_test view-5.1 { - execsql { - CREATE TABLE t2(y,a); - INSERT INTO t2 VALUES(22,2); - INSERT INTO t2 VALUES(33,3); - INSERT INTO t2 VALUES(44,4); - INSERT INTO t2 VALUES(55,5); - SELECT * FROM t2; - } -} {22 2 33 3 44 4 55 5} -do_test view-5.2 { - execsql { - CREATE VIEW v5 AS - SELECT t1.x AS v, t2.y AS w FROM t1 JOIN t2 USING(a); - SELECT * FROM v5; - } -} {1 22 4 55} - -# Verify that the view v5 gets flattened. see sqliteFlattenSubquery(). -# This will only work if EXPLAIN is enabled. -# Ticket #272 -# -ifcapable {explain} { -do_test view-5.3 { - lsearch [execsql { - EXPLAIN SELECT * FROM v5; - }] OpenTemp -} {-1} -do_test view-5.4 { - execsql { - SELECT * FROM v5 AS a, t2 AS b WHERE a.w=b.y; - } -} {1 22 22 2 4 55 55 5} -do_test view-5.5 { - lsearch [execsql { - EXPLAIN SELECT * FROM v5 AS a, t2 AS b WHERE a.w=b.y; - }] OpenTemp -} {-1} -do_test view-5.6 { - execsql { - SELECT * FROM t2 AS b, v5 AS a WHERE a.w=b.y; - } -} {22 2 1 22 55 5 4 55} -do_test view-5.7 { - lsearch [execsql { - EXPLAIN SELECT * FROM t2 AS b, v5 AS a WHERE a.w=b.y; - }] OpenTemp -} {-1} -do_test view-5.8 { - execsql { - SELECT * FROM t1 AS a, v5 AS b, t2 AS c WHERE a.x=b.v AND b.w=c.y; - } -} {1 2 3 4 1 22 22 2 4 5 6 7 4 55 55 5} -do_test view-5.9 { - lsearch [execsql { - EXPLAIN SELECT * FROM t1 AS a, v5 AS b, t2 AS c WHERE a.x=b.v AND b.w=c.y; - }] OpenTemp -} {-1} -} ;# endif explain - -do_test view-6.1 { - execsql { - SELECT min(x), min(a), min(b), min(c), min(a+b+c) FROM v2; - } -} {7 8 9 10 27} -do_test view-6.2 { - execsql { - SELECT max(x), max(a), max(b), max(c), max(a+b+c) FROM v2; - } -} {11 12 13 14 39} - -do_test view-7.1 { - execsql { - CREATE TABLE test1(id integer primary key, a); - CREATE TABLE test2(id integer, b); - INSERT INTO test1 VALUES(1,2); - INSERT INTO test2 VALUES(1,3); - CREATE VIEW test AS - SELECT test1.id, a, b - FROM test1 JOIN test2 ON test2.id=test1.id; - SELECT * FROM test; - } -} {1 2 3} -do_test view-7.2 { - db close - sqlite3 db test.db - execsql { - SELECT * FROM test; - } -} {1 2 3} -do_test view-7.3 { - execsql { - DROP VIEW test; - CREATE VIEW test AS - SELECT test1.id, a, b - FROM test1 JOIN test2 USING(id); - SELECT * FROM test; - } -} {1 2 3} -do_test view-7.4 { - db close - sqlite3 db test.db - execsql { - SELECT * FROM test; - } -} {1 2 3} -do_test view-7.5 { - execsql { - DROP VIEW test; - CREATE VIEW test AS - SELECT test1.id, a, b - FROM test1 NATURAL JOIN test2; - SELECT * FROM test; - } -} {1 2 3} -do_test view-7.6 { - db close - sqlite3 db test.db - execsql { - SELECT * FROM test; - } -} {1 2 3} - -do_test view-8.1 { - execsql { - CREATE VIEW v6 AS SELECT pqr, xyz FROM v1; - SELECT * FROM v6 ORDER BY xyz; - } -} {7 2 13 5 19 8 27 12} -do_test view-8.2 { - db close - sqlite3 db test.db - execsql { - SELECT * FROM v6 ORDER BY xyz; - } -} {7 2 13 5 19 8 27 12} -do_test view-8.3 { - execsql { - CREATE VIEW v7 AS SELECT pqr+xyz AS a FROM v6; - SELECT * FROM v7 ORDER BY a; - } -} {9 18 27 39} - -ifcapable subquery { - do_test view-8.4 { - execsql { - CREATE VIEW v8 AS SELECT max(cnt) AS mx FROM - (SELECT a%2 AS eo, count(*) AS cnt FROM t1 GROUP BY eo); - SELECT * FROM v8; - } - } 3 - do_test view-8.5 { - execsql { - SELECT mx+10, mx*2 FROM v8; - } - } {13 6} - do_test view-8.6 { - execsql { - SELECT mx+10, pqr FROM v6, v8 WHERE xyz=2; - } - } {13 7} - do_test view-8.7 { - execsql { - SELECT mx+10, pqr FROM v6, v8 WHERE xyz>2; - } - } {13 13 13 19 13 27} -} ;# ifcapable subquery - -# Tests for a bug found by Michiel de Wit involving ORDER BY in a VIEW. -# -do_test view-9.1 { - execsql { - INSERT INTO t2 SELECT * FROM t2 WHERE a<5; - INSERT INTO t2 SELECT * FROM t2 WHERE a<4; - INSERT INTO t2 SELECT * FROM t2 WHERE a<3; - SELECT DISTINCT count(*) FROM t2 GROUP BY a ORDER BY 1; - } -} {1 2 4 8} -do_test view-9.2 { - execsql { - SELECT DISTINCT count(*) FROM t2 GROUP BY a ORDER BY 1 LIMIT 3; - } -} {1 2 4} -do_test view-9.3 { - execsql { - CREATE VIEW v9 AS - SELECT DISTINCT count(*) FROM t2 GROUP BY a ORDER BY 1 LIMIT 3; - SELECT * FROM v9; - } -} {1 2 4} -do_test view-9.4 { - execsql { - SELECT * FROM v9 ORDER BY 1 DESC; - } -} {4 2 1} -do_test view-9.5 { - execsql { - CREATE VIEW v10 AS - SELECT DISTINCT a, count(*) FROM t2 GROUP BY a ORDER BY 2 LIMIT 3; - SELECT * FROM v10; - } -} {5 1 4 2 3 4} -do_test view-9.6 { - execsql { - SELECT * FROM v10 ORDER BY 1; - } -} {3 4 4 2 5 1} - -# Tables with columns having peculiar quoted names used in views -# Ticket #756. -# -do_test view-10.1 { - execsql { - CREATE TABLE t3("9" integer, [4] text); - INSERT INTO t3 VALUES(1,2); - CREATE VIEW v_t3_a AS SELECT a.[9] FROM t3 AS a; - CREATE VIEW v_t3_b AS SELECT "4" FROM t3; - SELECT * FROM v_t3_a; - } -} {1} -do_test view-10.2 { - execsql { - SELECT * FROM v_t3_b; - } -} {2} - -do_test view-11.1 { - execsql { - CREATE TABLE t4(a COLLATE NOCASE); - INSERT INTO t4 VALUES('This'); - INSERT INTO t4 VALUES('this'); - INSERT INTO t4 VALUES('THIS'); - SELECT * FROM t4 WHERE a = 'THIS'; - } -} {This this THIS} -do_test view-11.2 { - execsql { - SELECT * FROM (SELECT * FROM t4) WHERE a = 'THIS'; - } -} {This this THIS} -do_test view-11.3 { - execsql { - CREATE VIEW v11 AS SELECT * FROM t4; - SELECT * FROM v11 WHERE a = 'THIS'; - } -} {This this THIS} - -finish_test diff --git a/sqlite/test/where.test b/sqlite/test/where.test deleted file mode 100644 index a5dc3e0..0000000 --- a/sqlite/test/where.test +++ /dev/null @@ -1,842 +0,0 @@ -# 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 implements regression tests for SQLite library. The -# focus of this file is testing the use of indices in WHERE clases. -# -# $Id: where.test,v 1.28 2005/01/21 03:12:16 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Build some test data -# -do_test where-1.0 { - execsql { - CREATE TABLE t1(w int, x int, y int); - CREATE TABLE t2(p int, q int, r int, s int); - } - for {set i 1} {$i<=100} {incr i} { - set w $i - set x [expr {int(log($i)/log(2))}] - set y [expr {$i*$i + 2*$i + 1}] - execsql "INSERT INTO t1 VALUES($w,$x,$y)" - } - - ifcapable subquery { - execsql { - INSERT INTO t2 SELECT 101-w, x, (SELECT max(y) FROM t1)+1-y, y FROM t1; - } - } else { - set maxy [execsql {select max(y) from t1}] - execsql " - INSERT INTO t2 SELECT 101-w, x, $maxy+1-y, y FROM t1; - " - } - - execsql { - CREATE INDEX i1w ON t1(w); - CREATE INDEX i1xy ON t1(x,y); - CREATE INDEX i2p ON t2(p); - CREATE INDEX i2r ON t2(r); - CREATE INDEX i2qs ON t2(q, s); - } -} {} - -# Do an SQL statement. Append the search count to the end of the result. -# -proc count sql { - set ::sqlite_search_count 0 - return [concat [execsql $sql] $::sqlite_search_count] -} - -# Verify that queries use an index. We are using the special variable -# "sqlite_search_count" which tallys the number of executions of MoveTo -# and Next operators in the VDBE. By verifing that the search count is -# small we can be assured that indices are being used properly. -# -do_test where-1.1 { - count {SELECT x, y FROM t1 WHERE w=10} -} {3 121 3} -do_test where-1.2 { - count {SELECT x, y FROM t1 WHERE w=11} -} {3 144 3} -do_test where-1.3 { - count {SELECT x, y FROM t1 WHERE 11=w} -} {3 144 3} -do_test where-1.4 { - count {SELECT x, y FROM t1 WHERE 11=w AND x>2} -} {3 144 3} -do_test where-1.5 { - count {SELECT x, y FROM t1 WHERE y<200 AND w=11 AND x>2} -} {3 144 3} -do_test where-1.6 { - count {SELECT x, y FROM t1 WHERE y<200 AND x>2 AND w=11} -} {3 144 3} -do_test where-1.7 { - count {SELECT x, y FROM t1 WHERE w=11 AND y<200 AND x>2} -} {3 144 3} -do_test where-1.8 { - count {SELECT x, y FROM t1 WHERE w>10 AND y=144 AND x=3} -} {3 144 3} -do_test where-1.9 { - count {SELECT x, y FROM t1 WHERE y=144 AND w>10 AND x=3} -} {3 144 3} -do_test where-1.10 { - count {SELECT x, y FROM t1 WHERE x=3 AND w>=10 AND y=121} -} {3 121 3} -do_test where-1.11 { - count {SELECT x, y FROM t1 WHERE x=3 AND y=100 AND w<10} -} {3 100 3} - -# New for SQLite version 2.1: Verify that that inequality constraints -# are used correctly. -# -do_test where-1.12 { - count {SELECT w FROM t1 WHERE x=3 AND y<100} -} {8 3} -do_test where-1.13 { - count {SELECT w FROM t1 WHERE x=3 AND 100>y} -} {8 3} -do_test where-1.14 { - count {SELECT w FROM t1 WHERE 3=x AND y<100} -} {8 3} -do_test where-1.15 { - count {SELECT w FROM t1 WHERE 3=x AND 100>y} -} {8 3} -do_test where-1.16 { - count {SELECT w FROM t1 WHERE x=3 AND y<=100} -} {8 9 5} -do_test where-1.17 { - count {SELECT w FROM t1 WHERE x=3 AND 100>=y} -} {8 9 5} -do_test where-1.18 { - count {SELECT w FROM t1 WHERE x=3 AND y>225} -} {15 3} -do_test where-1.19 { - count {SELECT w FROM t1 WHERE x=3 AND 225=225} -} {14 15 5} -do_test where-1.21 { - count {SELECT w FROM t1 WHERE x=3 AND 225<=y} -} {14 15 5} -do_test where-1.22 { - count {SELECT w FROM t1 WHERE x=3 AND y>121 AND y<196} -} {11 12 5} -do_test where-1.23 { - count {SELECT w FROM t1 WHERE x=3 AND y>=121 AND y<=196} -} {10 11 12 13 9} -do_test where-1.24 { - count {SELECT w FROM t1 WHERE x=3 AND 121y} -} {11 12 5} -do_test where-1.25 { - count {SELECT w FROM t1 WHERE x=3 AND 121<=y AND 196>=y} -} {10 11 12 13 9} - -# Need to work on optimizing the BETWEEN operator. -# -# do_test where-1.26 { -# count {SELECT w FROM t1 WHERE x=3 AND y BETWEEN 121 AND 196} -# } {10 11 12 13 9} - -do_test where-1.27 { - count {SELECT w FROM t1 WHERE x=3 AND y+1==122} -} {10 17} - -do_test where-1.28 { - count {SELECT w FROM t1 WHERE x+1=4 AND y+1==122} -} {10 99} -do_test where-1.29 { - count {SELECT w FROM t1 WHERE y==121} -} {10 99} - - -do_test where-1.30 { - count {SELECT w FROM t1 WHERE w>97} -} {98 99 100 3} -do_test where-1.31 { - count {SELECT w FROM t1 WHERE w>=97} -} {97 98 99 100 4} -do_test where-1.33 { - count {SELECT w FROM t1 WHERE w==97} -} {97 2} -do_test where-1.33.1 { - count {SELECT w FROM t1 WHERE w<=97 AND w==97} -} {97 2} -do_test where-1.33.2 { - count {SELECT w FROM t1 WHERE w<98 AND w==97} -} {97 2} -do_test where-1.33.3 { - count {SELECT w FROM t1 WHERE w>=97 AND w==97} -} {97 2} -do_test where-1.33.4 { - count {SELECT w FROM t1 WHERE w>96 AND w==97} -} {97 2} -do_test where-1.33.5 { - count {SELECT w FROM t1 WHERE w==97 AND w==97} -} {97 2} -do_test where-1.34 { - count {SELECT w FROM t1 WHERE w+1==98} -} {97 99} -do_test where-1.35 { - count {SELECT w FROM t1 WHERE w<3} -} {1 2 2} -do_test where-1.36 { - count {SELECT w FROM t1 WHERE w<=3} -} {1 2 3 3} -do_test where-1.37 { - count {SELECT w FROM t1 WHERE w+1<=4 ORDER BY w} -} {1 2 3 99} - -do_test where-1.38 { - count {SELECT (w) FROM t1 WHERE (w)>(97)} -} {98 99 100 3} -do_test where-1.39 { - count {SELECT (w) FROM t1 WHERE (w)>=(97)} -} {97 98 99 100 4} -do_test where-1.40 { - count {SELECT (w) FROM t1 WHERE (w)==(97)} -} {97 2} -do_test where-1.41 { - count {SELECT (w) FROM t1 WHERE ((w)+(1))==(98)} -} {97 99} - - -# Do the same kind of thing except use a join as the data source. -# -do_test where-2.1 { - count { - SELECT w, p FROM t2, t1 - WHERE x=q AND y=s AND r=8977 - } -} {34 67 6} -do_test where-2.2 { - count { - SELECT w, p FROM t2, t1 - WHERE x=q AND s=y AND r=8977 - } -} {34 67 6} -do_test where-2.3 { - count { - SELECT w, p FROM t2, t1 - WHERE x=q AND s=y AND r=8977 AND w>10 - } -} {34 67 6} -do_test where-2.4 { - count { - SELECT w, p FROM t2, t1 - WHERE p<80 AND x=q AND s=y AND r=8977 AND w>10 - } -} {34 67 6} -do_test where-2.5 { - count { - SELECT w, p FROM t2, t1 - WHERE p<80 AND x=q AND 8977=r AND s=y AND w>10 - } -} {34 67 6} -do_test where-2.6 { - count { - SELECT w, p FROM t2, t1 - WHERE x=q AND p=77 AND s=y AND w>5 - } -} {24 77 6} -do_test where-2.7 { - count { - SELECT w, p FROM t1, t2 - WHERE x=q AND p>77 AND s=y AND w=5 - } -} {5 96 6} - -# Lets do a 3-way join. -# -do_test where-3.1 { - count { - SELECT A.w, B.p, C.w FROM t1 as A, t2 as B, t1 as C - WHERE C.w=101-B.p AND B.r=10202-A.y AND A.w=11 - } -} {11 90 11 8} -do_test where-3.2 { - count { - SELECT A.w, B.p, C.w FROM t1 as A, t2 as B, t1 as C - WHERE C.w=101-B.p AND B.r=10202-A.y AND A.w=12 - } -} {12 89 12 8} -do_test where-3.3 { - count { - SELECT A.w, B.p, C.w FROM t1 as A, t2 as B, t1 as C - WHERE A.w=15 AND B.p=C.w AND B.r=10202-A.y - } -} {15 86 86 8} - -# Test to see that the special case of a constant WHERE clause is -# handled. -# -do_test where-4.1 { - count { - SELECT * FROM t1 WHERE 0 - } -} {0} -do_test where-4.2 { - count { - SELECT * FROM t1 WHERE 1 LIMIT 1 - } -} {1 0 4 1} -do_test where-4.3 { - execsql { - SELECT 99 WHERE 0 - } -} {} -do_test where-4.4 { - execsql { - SELECT 99 WHERE 1 - } -} {99} - -# Verify that IN operators in a WHERE clause are handled correctly. -# Omit these tests if the build is not capable of sub-queries. -# -ifcapable subquery { - do_test where-5.1 { - count { - SELECT * FROM t1 WHERE rowid IN (1,2,3,1234) order by 1; - } - } {1 0 4 2 1 9 3 1 16 3} - do_test where-5.2 { - count { - SELECT * FROM t1 WHERE rowid+0 IN (1,2,3,1234) order by 1; - } - } {1 0 4 2 1 9 3 1 16 199} - do_test where-5.3 { - count { - SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1; - } - } {1 0 4 2 1 9 3 1 16 13} - do_test where-5.4 { - count { - SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1; - } - } {1 0 4 2 1 9 3 1 16 199} - do_test where-5.5 { - count { - SELECT * FROM t1 WHERE rowid IN - (select rowid from t1 where rowid IN (-1,2,4)) - ORDER BY 1; - } - } {2 1 9 4 2 25 3} - do_test where-5.6 { - count { - SELECT * FROM t1 WHERE rowid+0 IN - (select rowid from t1 where rowid IN (-1,2,4)) - ORDER BY 1; - } - } {2 1 9 4 2 25 201} - do_test where-5.7 { - count { - SELECT * FROM t1 WHERE w IN - (select rowid from t1 where rowid IN (-1,2,4)) - ORDER BY 1; - } - } {2 1 9 4 2 25 9} - do_test where-5.8 { - count { - SELECT * FROM t1 WHERE w+0 IN - (select rowid from t1 where rowid IN (-1,2,4)) - ORDER BY 1; - } - } {2 1 9 4 2 25 201} - do_test where-5.9 { - count { - SELECT * FROM t1 WHERE x IN (1,7) ORDER BY 1; - } - } {2 1 9 3 1 16 7} - do_test where-5.10 { - count { - SELECT * FROM t1 WHERE x+0 IN (1,7) ORDER BY 1; - } - } {2 1 9 3 1 16 199} - do_test where-5.11 { - count { - SELECT * FROM t1 WHERE y IN (6400,8100) ORDER BY 1; - } - } {79 6 6400 89 6 8100 199} - do_test where-5.12 { - count { - SELECT * FROM t1 WHERE x=6 AND y IN (6400,8100) ORDER BY 1; - } - } {79 6 6400 89 6 8100 74} - do_test where-5.13 { - count { - SELECT * FROM t1 WHERE x IN (1,7) AND y NOT IN (6400,8100) ORDER BY 1; - } - } {2 1 9 3 1 16 7} - do_test where-5.14 { - count { - SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,10) ORDER BY 1; - } - } {2 1 9 7} -} - -# This procedure executes the SQL. Then it checks to see if the OP_Sort -# opcode was executed. If an OP_Sort did occur, then "sort" is appended -# to the result. If no OP_Sort happened, then "nosort" is appended. -# -# This procedure is used to check to make sure sorting is or is not -# occurring as expected. -# -proc cksort {sql} { - set ::sqlite_sort_count 0 - set data [execsql $sql] - if {$::sqlite_sort_count} {set x sort} {set x nosort} - lappend data $x - return $data -} -# Check out the logic that attempts to implement the ORDER BY clause -# using an index rather than by sorting. -# -do_test where-6.1 { - execsql { - CREATE TABLE t3(a,b,c); - CREATE INDEX t3a ON t3(a); - CREATE INDEX t3bc ON t3(b,c); - CREATE INDEX t3acb ON t3(a,c,b); - INSERT INTO t3 SELECT w, 101-w, y FROM t1; - SELECT count(*), sum(a), sum(b), sum(c) FROM t3; - } -} {100 5050.0 5050.0 348550.0} -do_test where-6.2 { - cksort { - SELECT * FROM t3 ORDER BY a LIMIT 3 - } -} {1 100 4 2 99 9 3 98 16 nosort} -do_test where-6.3 { - cksort { - SELECT * FROM t3 ORDER BY a+1 LIMIT 3 - } -} {1 100 4 2 99 9 3 98 16 sort} -do_test where-6.4 { - cksort { - SELECT * FROM t3 WHERE a<10 ORDER BY a LIMIT 3 - } -} {1 100 4 2 99 9 3 98 16 nosort} -do_test where-6.5 { - cksort { - SELECT * FROM t3 WHERE a>0 AND a<10 ORDER BY a LIMIT 3 - } -} {1 100 4 2 99 9 3 98 16 nosort} -do_test where-6.6 { - cksort { - SELECT * FROM t3 WHERE a>0 ORDER BY a LIMIT 3 - } -} {1 100 4 2 99 9 3 98 16 nosort} -do_test where-6.7 { - cksort { - SELECT * FROM t3 WHERE b>0 ORDER BY a LIMIT 3 - } -} {1 100 4 2 99 9 3 98 16 sort} -ifcapable subquery { - do_test where-6.8 { - cksort { - SELECT * FROM t3 WHERE a IN (3,5,7,1,9,4,2) ORDER BY a LIMIT 3 - } - } {1 100 4 2 99 9 3 98 16 sort} -} -do_test where-6.9.1 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.9.1.1 { - cksort { - SELECT * FROM t3 WHERE a>=1 AND a=1 AND c>0 ORDER BY a LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.9.1.2 { - cksort { - SELECT * FROM t3 WHERE a<2 AND a=1 AND c>0 ORDER BY a LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.9.2 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a,c LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.9.3 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY c LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.9.4 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a DESC LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.9.5 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a DESC, c DESC LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.9.6 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY c DESC LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.9.7 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY c,a LIMIT 3 - } -} {1 100 4 sort} -do_test where-6.9.8 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a DESC, c ASC LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.9.9 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a ASC, c DESC LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.10 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.11 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a,c LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.12 { - cksort { - SELECT * FROM t3 WHERE a=1 AND c>0 ORDER BY a,c,b LIMIT 3 - } -} {1 100 4 nosort} -do_test where-6.13 { - cksort { - SELECT * FROM t3 WHERE a>0 ORDER BY a DESC LIMIT 3 - } -} {100 1 10201 99 2 10000 98 3 9801 nosort} -do_test where-6.13.1 { - cksort { - SELECT * FROM t3 WHERE a>0 ORDER BY -a LIMIT 3 - } -} {100 1 10201 99 2 10000 98 3 9801 sort} -do_test where-6.14 { - cksort { - SELECT * FROM t3 ORDER BY b LIMIT 3 - } -} {100 1 10201 99 2 10000 98 3 9801 nosort} -do_test where-6.15 { - cksort { - SELECT t3.a, t1.x FROM t3, t1 WHERE t3.a=t1.w ORDER BY t3.a LIMIT 3 - } -} {1 0 2 1 3 1 nosort} -do_test where-6.16 { - cksort { - SELECT t3.a, t1.x FROM t3, t1 WHERE t3.a=t1.w ORDER BY t1.x, t3.a LIMIT 3 - } -} {1 0 2 1 3 1 sort} -do_test where-6.19 { - cksort { - SELECT y FROM t1 ORDER BY w LIMIT 3; - } -} {4 9 16 nosort} -do_test where-6.20 { - cksort { - SELECT y FROM t1 ORDER BY rowid LIMIT 3; - } -} {4 9 16 nosort} -do_test where-6.21 { - cksort { - SELECT y FROM t1 ORDER BY rowid, y LIMIT 3; - } -} {4 9 16 nosort} -do_test where-6.22 { - cksort { - SELECT y FROM t1 ORDER BY rowid, y DESC LIMIT 3; - } -} {4 9 16 nosort} -do_test where-6.23 { - cksort { - SELECT y FROM t1 WHERE y>4 ORDER BY rowid, w, x LIMIT 3; - } -} {9 16 25 nosort} -do_test where-6.24 { - cksort { - SELECT y FROM t1 WHERE y>=9 ORDER BY rowid, x DESC, w LIMIT 3; - } -} {9 16 25 nosort} -do_test where-6.25 { - cksort { - SELECT y FROM t1 WHERE y>4 AND y<25 ORDER BY rowid; - } -} {9 16 nosort} -do_test where-6.26 { - cksort { - SELECT y FROM t1 WHERE y>=4 AND y<=25 ORDER BY oid; - } -} {4 9 16 25 nosort} -do_test where-6.27 { - cksort { - SELECT y FROM t1 WHERE y<=25 ORDER BY _rowid_, w+y; - } -} {4 9 16 25 nosort} - - -# Tests for reverse-order sorting. -# -do_test where-7.1 { - cksort { - SELECT w FROM t1 WHERE x=3 ORDER BY y; - } -} {8 9 10 11 12 13 14 15 nosort} -do_test where-7.2 { - cksort { - SELECT w FROM t1 WHERE x=3 ORDER BY y DESC; - } -} {15 14 13 12 11 10 9 8 nosort} -do_test where-7.3 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>100 ORDER BY y LIMIT 3; - } -} {10 11 12 nosort} -do_test where-7.4 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>100 ORDER BY y DESC LIMIT 3; - } -} {15 14 13 nosort} -do_test where-7.5 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>121 ORDER BY y DESC; - } -} {15 14 13 12 11 nosort} -do_test where-7.6 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>=121 ORDER BY y DESC; - } -} {15 14 13 12 11 10 nosort} -do_test where-7.7 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>=121 AND y<196 ORDER BY y DESC; - } -} {12 11 10 nosort} -do_test where-7.8 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>=121 AND y<=196 ORDER BY y DESC; - } -} {13 12 11 10 nosort} -do_test where-7.9 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>121 AND y<=196 ORDER BY y DESC; - } -} {13 12 11 nosort} -do_test where-7.10 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>100 AND y<196 ORDER BY y DESC; - } -} {12 11 10 nosort} -do_test where-7.11 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>=121 AND y<196 ORDER BY y; - } -} {10 11 12 nosort} -do_test where-7.12 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>=121 AND y<=196 ORDER BY y; - } -} {10 11 12 13 nosort} -do_test where-7.13 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>121 AND y<=196 ORDER BY y; - } -} {11 12 13 nosort} -do_test where-7.14 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>100 AND y<196 ORDER BY y; - } -} {10 11 12 nosort} -do_test where-7.15 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y<81 ORDER BY y; - } -} {nosort} -do_test where-7.16 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y<=81 ORDER BY y; - } -} {8 nosort} -do_test where-7.17 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>256 ORDER BY y; - } -} {nosort} -do_test where-7.18 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>=256 ORDER BY y; - } -} {15 nosort} -do_test where-7.19 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y<81 ORDER BY y DESC; - } -} {nosort} -do_test where-7.20 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y<=81 ORDER BY y DESC; - } -} {8 nosort} -do_test where-7.21 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>256 ORDER BY y DESC; - } -} {nosort} -do_test where-7.22 { - cksort { - SELECT w FROM t1 WHERE x=3 AND y>=256 ORDER BY y DESC; - } -} {15 nosort} -do_test where-7.23 { - cksort { - SELECT w FROM t1 WHERE x=0 AND y<4 ORDER BY y; - } -} {nosort} -do_test where-7.24 { - cksort { - SELECT w FROM t1 WHERE x=0 AND y<=4 ORDER BY y; - } -} {1 nosort} -do_test where-7.25 { - cksort { - SELECT w FROM t1 WHERE x=6 AND y>10201 ORDER BY y; - } -} {nosort} -do_test where-7.26 { - cksort { - SELECT w FROM t1 WHERE x=6 AND y>=10201 ORDER BY y; - } -} {100 nosort} -do_test where-7.27 { - cksort { - SELECT w FROM t1 WHERE x=0 AND y<4 ORDER BY y DESC; - } -} {nosort} -do_test where-7.28 { - cksort { - SELECT w FROM t1 WHERE x=0 AND y<=4 ORDER BY y DESC; - } -} {1 nosort} -do_test where-7.29 { - cksort { - SELECT w FROM t1 WHERE x=6 AND y>10201 ORDER BY y DESC; - } -} {nosort} -do_test where-7.30 { - cksort { - SELECT w FROM t1 WHERE x=6 AND y>=10201 ORDER BY y DESC; - } -} {100 nosort} -do_test where-7.31 { - cksort { - SELECT y FROM t1 ORDER BY rowid DESC LIMIT 3 - } -} {10201 10000 9801 nosort} -do_test where-7.32 { - cksort { - SELECT y FROM t1 WHERE y<25 ORDER BY rowid DESC, x - } -} {16 9 4 nosort} -do_test where-7.33 { - cksort { - SELECT y FROM t1 WHERE y<=25 ORDER BY rowid DESC, x - } -} {25 16 9 4 nosort} -do_test where-7.34 { - cksort { - SELECT y FROM t1 WHERE y<25 AND y>4 ORDER BY rowid DESC, y DESC - } -} {16 9 nosort} -do_test where-7.35 { - cksort { - SELECT y FROM t1 WHERE y<25 AND y>=4 ORDER BY rowid DESC - } -} {16 9 4 nosort} - -do_test where-8.1 { - execsql { - CREATE TABLE t4 AS SELECT * FROM t1; - CREATE INDEX i4xy ON t4(x,y); - } - cksort { - SELECT w FROM t4 WHERE x=4 and y<1000 ORDER BY y DESC limit 3; - } -} {30 29 28 nosort} -do_test where-8.2 { - execsql { - DELETE FROM t4; - } - cksort { - SELECT w FROM t4 WHERE x=4 and y<1000 ORDER BY y DESC limit 3; - } -} {nosort} - -# Make sure searches with an index work with an empty table. -# -do_test where-9.1 { - execsql { - CREATE TABLE t5(x PRIMARY KEY); - SELECT * FROM t5 WHERE x<10; - } -} {} -do_test where-9.2 { - execsql { - SELECT * FROM t5 WHERE x<10 ORDER BY x DESC; - } -} {} -do_test where-9.3 { - execsql { - SELECT * FROM t5 WHERE x=10; - } -} {} - -do_test where-10.1 { - execsql { - SELECT 1 WHERE abs(random())<0 - } -} {} -do_test where-10.2 { - proc tclvar_func {vname} {return [set ::$vname]} - db function tclvar tclvar_func - set ::v1 0 - execsql { - SELECT count(*) FROM t1 WHERE tclvar('v1'); - } -} {0} -do_test where-10.3 { - set ::v1 1 - execsql { - SELECT count(*) FROM t1 WHERE tclvar('v1'); - } -} {100} -do_test where-10.4 { - set ::v1 1 - proc tclvar_func {vname} { - upvar #0 $vname v - set v [expr {!$v}] - return $v - } - execsql { - SELECT count(*) FROM t1 WHERE tclvar('v1'); - } -} {50} - -integrity_check {where-99.0} - -finish_test diff --git a/sqlite/tool/lemon.c b/sqlite/tool/lemon.c deleted file mode 100644 index b24dd02..0000000 --- a/sqlite/tool/lemon.c +++ /dev/null @@ -1,4588 +0,0 @@ -/* -** This file contains all sources (including headers) to the LEMON -** LALR(1) parser generator. The sources have been combined into a -** single file to make it easy to include LEMON in the source tree -** and Makefile of another program. -** -** The author of this program disclaims copyright. -*/ -#include -#include -#include -#include -#include - -#ifndef __WIN32__ -# if defined(_WIN32) || defined(WIN32) -# define __WIN32__ -# endif -#endif - -/* #define PRIVATE static */ -#define PRIVATE - -#ifdef TEST -#define MAXRHS 5 /* Set low to exercise exception code */ -#else -#define MAXRHS 1000 -#endif - -char *msort(); -extern void *malloc(); - -/******** From the file "action.h" *************************************/ -struct action *Action_new(); -struct action *Action_sort(); - -/********* From the file "assert.h" ************************************/ -void myassert(); -#ifndef NDEBUG -# define assert(X) if(!(X))myassert(__FILE__,__LINE__) -#else -# define assert(X) -#endif - -/********** From the file "build.h" ************************************/ -void FindRulePrecedences(); -void FindFirstSets(); -void FindStates(); -void FindLinks(); -void FindFollowSets(); -void FindActions(); - -/********* From the file "configlist.h" *********************************/ -void Configlist_init(/* void */); -struct config *Configlist_add(/* struct rule *, int */); -struct config *Configlist_addbasis(/* struct rule *, int */); -void Configlist_closure(/* void */); -void Configlist_sort(/* void */); -void Configlist_sortbasis(/* void */); -struct config *Configlist_return(/* void */); -struct config *Configlist_basis(/* void */); -void Configlist_eat(/* struct config * */); -void Configlist_reset(/* void */); - -/********* From the file "error.h" ***************************************/ -void ErrorMsg(const char *, int,const char *, ...); - -/****** From the file "option.h" ******************************************/ -struct s_options { - enum { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR, - OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR} type; - char *label; - char *arg; - char *message; -}; -int OptInit(/* char**,struct s_options*,FILE* */); -int OptNArgs(/* void */); -char *OptArg(/* int */); -void OptErr(/* int */); -void OptPrint(/* void */); - -/******** From the file "parse.h" *****************************************/ -void Parse(/* struct lemon *lemp */); - -/********* From the file "plink.h" ***************************************/ -struct plink *Plink_new(/* void */); -void Plink_add(/* struct plink **, struct config * */); -void Plink_copy(/* struct plink **, struct plink * */); -void Plink_delete(/* struct plink * */); - -/********** From the file "report.h" *************************************/ -void Reprint(/* struct lemon * */); -void ReportOutput(/* struct lemon * */); -void ReportTable(/* struct lemon * */); -void ReportHeader(/* struct lemon * */); -void CompressTables(/* struct lemon * */); - -/********** From the file "set.h" ****************************************/ -void SetSize(/* int N */); /* All sets will be of size N */ -char *SetNew(/* void */); /* A new set for element 0..N */ -void SetFree(/* char* */); /* Deallocate a set */ - -int SetAdd(/* char*,int */); /* Add element to a set */ -int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */ - -#define SetFind(X,Y) (X[Y]) /* True if Y is in set X */ - -/********** From the file "struct.h" *************************************/ -/* -** Principal data structures for the LEMON parser generator. -*/ - -typedef enum {B_FALSE=0, B_TRUE} Boolean; - -/* Symbols (terminals and nonterminals) of the grammar are stored -** in the following: */ -struct symbol { - char *name; /* Name of the symbol */ - int index; /* Index number for this symbol */ - enum { - TERMINAL, - NONTERMINAL - } type; /* Symbols are all either TERMINALS or NTs */ - struct rule *rule; /* Linked list of rules of this (if an NT) */ - struct symbol *fallback; /* fallback token in case this token doesn't parse */ - int prec; /* Precedence if defined (-1 otherwise) */ - enum e_assoc { - LEFT, - RIGHT, - NONE, - UNK - } assoc; /* Associativity if predecence is defined */ - char *firstset; /* First-set for all rules of this symbol */ - Boolean lambda; /* True if NT and can generate an empty string */ - char *destructor; /* Code which executes whenever this symbol is - ** popped from the stack during error processing */ - int destructorln; /* Line number of destructor code */ - char *datatype; /* The data type of information held by this - ** object. Only used if type==NONTERMINAL */ - int dtnum; /* The data type number. In the parser, the value - ** stack is a union. The .yy%d element of this - ** union is the correct data type for this object */ -}; - -/* Each production rule in the grammar is stored in the following -** structure. */ -struct rule { - struct symbol *lhs; /* Left-hand side of the rule */ - char *lhsalias; /* Alias for the LHS (NULL if none) */ - int ruleline; /* Line number for the rule */ - int nrhs; /* Number of RHS symbols */ - struct symbol **rhs; /* The RHS symbols */ - char **rhsalias; /* An alias for each RHS symbol (NULL if none) */ - int line; /* Line number at which code begins */ - char *code; /* The code executed when this rule is reduced */ - struct symbol *precsym; /* Precedence symbol for this rule */ - int index; /* An index number for this rule */ - Boolean canReduce; /* True if this rule is ever reduced */ - struct rule *nextlhs; /* Next rule with the same LHS */ - struct rule *next; /* Next rule in the global list */ -}; - -/* A configuration is a production rule of the grammar together with -** a mark (dot) showing how much of that rule has been processed so far. -** Configurations also contain a follow-set which is a list of terminal -** symbols which are allowed to immediately follow the end of the rule. -** Every configuration is recorded as an instance of the following: */ -struct config { - struct rule *rp; /* The rule upon which the configuration is based */ - int dot; /* The parse point */ - char *fws; /* Follow-set for this configuration only */ - struct plink *fplp; /* Follow-set forward propagation links */ - struct plink *bplp; /* Follow-set backwards propagation links */ - struct state *stp; /* Pointer to state which contains this */ - enum { - COMPLETE, /* The status is used during followset and */ - INCOMPLETE /* shift computations */ - } status; - struct config *next; /* Next configuration in the state */ - struct config *bp; /* The next basis configuration */ -}; - -/* Every shift or reduce operation is stored as one of the following */ -struct action { - struct symbol *sp; /* The look-ahead symbol */ - enum e_action { - SHIFT, - ACCEPT, - REDUCE, - ERROR, - CONFLICT, /* Was a reduce, but part of a conflict */ - SH_RESOLVED, /* Was a shift. Precedence resolved conflict */ - RD_RESOLVED, /* Was reduce. Precedence resolved conflict */ - NOT_USED /* Deleted by compression */ - } type; - union { - struct state *stp; /* The new state, if a shift */ - struct rule *rp; /* The rule, if a reduce */ - } x; - struct action *next; /* Next action for this state */ - struct action *collide; /* Next action with the same hash */ -}; - -/* Each state of the generated parser's finite state machine -** is encoded as an instance of the following structure. */ -struct state { - struct config *bp; /* The basis configurations for this state */ - struct config *cfp; /* All configurations in this set */ - int index; /* Sequencial number for this state */ - struct action *ap; /* Array of actions for this state */ - int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */ - int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */ - int iDflt; /* Default action */ -}; -#define NO_OFFSET (-2147483647) - -/* A followset propagation link indicates that the contents of one -** configuration followset should be propagated to another whenever -** the first changes. */ -struct plink { - struct config *cfp; /* The configuration to which linked */ - struct plink *next; /* The next propagate link */ -}; - -/* The state vector for the entire parser generator is recorded as -** follows. (LEMON uses no global variables and makes little use of -** static variables. Fields in the following structure can be thought -** of as begin global variables in the program.) */ -struct lemon { - struct state **sorted; /* Table of states sorted by state number */ - struct rule *rule; /* List of all rules */ - int nstate; /* Number of states */ - int nrule; /* Number of rules */ - int nsymbol; /* Number of terminal and nonterminal symbols */ - int nterminal; /* Number of terminal symbols */ - struct symbol **symbols; /* Sorted array of pointers to symbols */ - int errorcnt; /* Number of errors */ - struct symbol *errsym; /* The error symbol */ - char *name; /* Name of the generated parser */ - char *arg; /* Declaration of the 3th argument to parser */ - char *tokentype; /* Type of terminal symbols in the parser stack */ - char *vartype; /* The default type of non-terminal symbols */ - char *start; /* Name of the start symbol for the grammar */ - char *stacksize; /* Size of the parser stack */ - char *include; /* Code to put at the start of the C file */ - int includeln; /* Line number for start of include code */ - char *error; /* Code to execute when an error is seen */ - int errorln; /* Line number for start of error code */ - char *overflow; /* Code to execute on a stack overflow */ - int overflowln; /* Line number for start of overflow code */ - char *failure; /* Code to execute on parser failure */ - int failureln; /* Line number for start of failure code */ - char *accept; /* Code to execute when the parser excepts */ - int acceptln; /* Line number for the start of accept code */ - char *extracode; /* Code appended to the generated file */ - int extracodeln; /* Line number for the start of the extra code */ - char *tokendest; /* Code to execute to destroy token data */ - int tokendestln; /* Line number for token destroyer code */ - char *vardest; /* Code for the default non-terminal destructor */ - int vardestln; /* Line number for default non-term destructor code*/ - char *filename; /* Name of the input file */ - char *outname; /* Name of the current output file */ - char *tokenprefix; /* A prefix added to token names in the .h file */ - int nconflict; /* Number of parsing conflicts */ - int tablesize; /* Size of the parse tables */ - int basisflag; /* Print only basis configurations */ - int has_fallback; /* True if any %fallback is seen in the grammer */ - char *argv0; /* Name of the program */ -}; - -#define MemoryCheck(X) if((X)==0){ \ - extern void memory_error(); \ - memory_error(); \ -} - -/**************** From the file "table.h" *********************************/ -/* -** All code in this file has been automatically generated -** from a specification in the file -** "table.q" -** by the associative array code building program "aagen". -** Do not edit this file! Instead, edit the specification -** file, then rerun aagen. -*/ -/* -** Code for processing tables in the LEMON parser generator. -*/ - -/* Routines for handling a strings */ - -char *Strsafe(); - -void Strsafe_init(/* void */); -int Strsafe_insert(/* char * */); -char *Strsafe_find(/* char * */); - -/* Routines for handling symbols of the grammar */ - -struct symbol *Symbol_new(); -int Symbolcmpp(/* struct symbol **, struct symbol ** */); -void Symbol_init(/* void */); -int Symbol_insert(/* struct symbol *, char * */); -struct symbol *Symbol_find(/* char * */); -struct symbol *Symbol_Nth(/* int */); -int Symbol_count(/* */); -struct symbol **Symbol_arrayof(/* */); - -/* Routines to manage the state table */ - -int Configcmp(/* struct config *, struct config * */); -struct state *State_new(); -void State_init(/* void */); -int State_insert(/* struct state *, struct config * */); -struct state *State_find(/* struct config * */); -struct state **State_arrayof(/* */); - -/* Routines used for efficiency in Configlist_add */ - -void Configtable_init(/* void */); -int Configtable_insert(/* struct config * */); -struct config *Configtable_find(/* struct config * */); -void Configtable_clear(/* int(*)(struct config *) */); -/****************** From the file "action.c" *******************************/ -/* -** Routines processing parser actions in the LEMON parser generator. -*/ - -/* Allocate a new parser action */ -struct action *Action_new(){ - static struct action *freelist = 0; - struct action *new; - - if( freelist==0 ){ - int i; - int amt = 100; - freelist = (struct action *)malloc( sizeof(struct action)*amt ); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new parser action."); - exit(1); - } - for(i=0; inext; - return new; -} - -/* Compare two actions */ -static int actioncmp(ap1,ap2) -struct action *ap1; -struct action *ap2; -{ - int rc; - rc = ap1->sp->index - ap2->sp->index; - if( rc==0 ) rc = (int)ap1->type - (int)ap2->type; - if( rc==0 ){ - assert( ap1->type==REDUCE || ap1->type==RD_RESOLVED || ap1->type==CONFLICT); - assert( ap2->type==REDUCE || ap2->type==RD_RESOLVED || ap2->type==CONFLICT); - rc = ap1->x.rp->index - ap2->x.rp->index; - } - return rc; -} - -/* Sort parser actions */ -struct action *Action_sort(ap) -struct action *ap; -{ - ap = (struct action *)msort((char *)ap,(char **)&ap->next,actioncmp); - return ap; -} - -void Action_add(app,type,sp,arg) -struct action **app; -enum e_action type; -struct symbol *sp; -char *arg; -{ - struct action *new; - new = Action_new(); - new->next = *app; - *app = new; - new->type = type; - new->sp = sp; - if( type==SHIFT ){ - new->x.stp = (struct state *)arg; - }else{ - new->x.rp = (struct rule *)arg; - } -} -/********************** New code to implement the "acttab" module ***********/ -/* -** This module implements routines use to construct the yy_action[] table. -*/ - -/* -** The state of the yy_action table under construction is an instance of -** the following structure -*/ -typedef struct acttab acttab; -struct acttab { - int nAction; /* Number of used slots in aAction[] */ - int nActionAlloc; /* Slots allocated for aAction[] */ - struct { - int lookahead; /* Value of the lookahead token */ - int action; /* Action to take on the given lookahead */ - } *aAction, /* The yy_action[] table under construction */ - *aLookahead; /* A single new transaction set */ - int mnLookahead; /* Minimum aLookahead[].lookahead */ - int mnAction; /* Action associated with mnLookahead */ - int mxLookahead; /* Maximum aLookahead[].lookahead */ - int nLookahead; /* Used slots in aLookahead[] */ - int nLookaheadAlloc; /* Slots allocated in aLookahead[] */ -}; - -/* Return the number of entries in the yy_action table */ -#define acttab_size(X) ((X)->nAction) - -/* The value for the N-th entry in yy_action */ -#define acttab_yyaction(X,N) ((X)->aAction[N].action) - -/* The value for the N-th entry in yy_lookahead */ -#define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) - -/* Free all memory associated with the given acttab */ -void acttab_free(acttab *p){ - free( p->aAction ); - free( p->aLookahead ); - free( p ); -} - -/* Allocate a new acttab structure */ -acttab *acttab_alloc(void){ - acttab *p = malloc( sizeof(*p) ); - if( p==0 ){ - fprintf(stderr,"Unable to allocate memory for a new acttab."); - exit(1); - } - memset(p, 0, sizeof(*p)); - return p; -} - -/* Add a new action to the current transaction set -*/ -void acttab_action(acttab *p, int lookahead, int action){ - if( p->nLookahead>=p->nLookaheadAlloc ){ - p->nLookaheadAlloc += 25; - p->aLookahead = realloc( p->aLookahead, - sizeof(p->aLookahead[0])*p->nLookaheadAlloc ); - if( p->aLookahead==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - } - if( p->nLookahead==0 ){ - p->mxLookahead = lookahead; - p->mnLookahead = lookahead; - p->mnAction = action; - }else{ - if( p->mxLookaheadmxLookahead = lookahead; - if( p->mnLookahead>lookahead ){ - p->mnLookahead = lookahead; - p->mnAction = action; - } - } - p->aLookahead[p->nLookahead].lookahead = lookahead; - p->aLookahead[p->nLookahead].action = action; - p->nLookahead++; -} - -/* -** Add the transaction set built up with prior calls to acttab_action() -** into the current action table. Then reset the transaction set back -** to an empty set in preparation for a new round of acttab_action() calls. -** -** Return the offset into the action table of the new transaction. -*/ -int acttab_insert(acttab *p){ - int i, j, k, n; - assert( p->nLookahead>0 ); - - /* Make sure we have enough space to hold the expanded action table - ** in the worst case. The worst case occurs if the transaction set - ** must be appended to the current action table - */ - n = p->mxLookahead + 1; - if( p->nAction + n >= p->nActionAlloc ){ - int oldAlloc = p->nActionAlloc; - p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; - p->aAction = realloc( p->aAction, - sizeof(p->aAction[0])*p->nActionAlloc); - if( p->aAction==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=oldAlloc; inActionAlloc; i++){ - p->aAction[i].lookahead = -1; - p->aAction[i].action = -1; - } - } - - /* Scan the existing action table looking for an offset where we can - ** insert the current transaction set. Fall out of the loop when that - ** offset is found. In the worst case, we fall out of the loop when - ** i reaches p->nAction, which means we append the new transaction set. - ** - ** i is the index in p->aAction[] where p->mnLookahead is inserted. - */ - for(i=0; inAction+p->mnLookahead; i++){ - if( p->aAction[i].lookahead<0 ){ - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 ) break; - if( p->aAction[k].lookahead>=0 ) break; - } - if( jnLookahead ) continue; - for(j=0; jnAction; j++){ - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break; - } - if( j==p->nAction ){ - break; /* Fits in empty slots */ - } - }else if( p->aAction[i].lookahead==p->mnLookahead ){ - if( p->aAction[i].action!=p->mnAction ) continue; - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 || k>=p->nAction ) break; - if( p->aLookahead[j].lookahead!=p->aAction[k].lookahead ) break; - if( p->aLookahead[j].action!=p->aAction[k].action ) break; - } - if( jnLookahead ) continue; - n = 0; - for(j=0; jnAction; j++){ - if( p->aAction[j].lookahead<0 ) continue; - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++; - } - if( n==p->nLookahead ){ - break; /* Same as a prior transaction set */ - } - } - } - /* Insert transaction set at index i. */ - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - p->aAction[k] = p->aLookahead[j]; - if( k>=p->nAction ) p->nAction = k+1; - } - p->nLookahead = 0; - - /* Return the offset that is added to the lookahead in order to get the - ** index into yy_action of the action */ - return i - p->mnLookahead; -} - -/********************** From the file "assert.c" ****************************/ -/* -** A more efficient way of handling assertions. -*/ -void myassert(file,line) -char *file; -int line; -{ - fprintf(stderr,"Assertion failed on line %d of file \"%s\"\n",line,file); - exit(1); -} -/********************** From the file "build.c" *****************************/ -/* -** Routines to construction the finite state machine for the LEMON -** parser generator. -*/ - -/* Find a precedence symbol of every rule in the grammar. -** -** Those rules which have a precedence symbol coded in the input -** grammar using the "[symbol]" construct will already have the -** rp->precsym field filled. Other rules take as their precedence -** symbol the first RHS symbol with a defined precedence. If there -** are not RHS symbols with a defined precedence, the precedence -** symbol field is left blank. -*/ -void FindRulePrecedences(xp) -struct lemon *xp; -{ - struct rule *rp; - for(rp=xp->rule; rp; rp=rp->next){ - if( rp->precsym==0 ){ - int i; - for(i=0; inrhs; i++){ - if( rp->rhs[i]->prec>=0 ){ - rp->precsym = rp->rhs[i]; - break; - } - } - } - } - return; -} - -/* Find all nonterminals which will generate the empty string. -** Then go back and compute the first sets of every nonterminal. -** The first set is the set of all terminal symbols which can begin -** a string generated by that nonterminal. -*/ -void FindFirstSets(lemp) -struct lemon *lemp; -{ - int i; - struct rule *rp; - int progress; - - for(i=0; insymbol; i++){ - lemp->symbols[i]->lambda = B_FALSE; - } - for(i=lemp->nterminal; insymbol; i++){ - lemp->symbols[i]->firstset = SetNew(); - } - - /* First compute all lambdas */ - do{ - progress = 0; - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->lhs->lambda ) continue; - for(i=0; inrhs; i++){ - if( rp->rhs[i]->lambda==B_FALSE ) break; - } - if( i==rp->nrhs ){ - rp->lhs->lambda = B_TRUE; - progress = 1; - } - } - }while( progress ); - - /* Now compute all first sets */ - do{ - struct symbol *s1, *s2; - progress = 0; - for(rp=lemp->rule; rp; rp=rp->next){ - s1 = rp->lhs; - for(i=0; inrhs; i++){ - s2 = rp->rhs[i]; - if( s2->type==TERMINAL ){ - progress += SetAdd(s1->firstset,s2->index); - break; - }else if( s1==s2 ){ - if( s1->lambda==B_FALSE ) break; - }else{ - progress += SetUnion(s1->firstset,s2->firstset); - if( s2->lambda==B_FALSE ) break; - } - } - } - }while( progress ); - return; -} - -/* Compute all LR(0) states for the grammar. Links -** are added to between some states so that the LR(1) follow sets -** can be computed later. -*/ -PRIVATE struct state *getstate(/* struct lemon * */); /* forward reference */ -void FindStates(lemp) -struct lemon *lemp; -{ - struct symbol *sp; - struct rule *rp; - - Configlist_init(); - - /* Find the start symbol */ - if( lemp->start ){ - sp = Symbol_find(lemp->start); - if( sp==0 ){ - ErrorMsg(lemp->filename,0, -"The specified start symbol \"%s\" is not \ -in a nonterminal of the grammar. \"%s\" will be used as the start \ -symbol instead.",lemp->start,lemp->rule->lhs->name); - lemp->errorcnt++; - sp = lemp->rule->lhs; - } - }else{ - sp = lemp->rule->lhs; - } - - /* Make sure the start symbol doesn't occur on the right-hand side of - ** any rule. Report an error if it does. (YACC would generate a new - ** start symbol in this case.) */ - for(rp=lemp->rule; rp; rp=rp->next){ - int i; - for(i=0; inrhs; i++){ - if( rp->rhs[i]==sp ){ - ErrorMsg(lemp->filename,0, -"The start symbol \"%s\" occurs on the \ -right-hand side of a rule. This will result in a parser which \ -does not work properly.",sp->name); - lemp->errorcnt++; - } - } - } - - /* The basis configuration set for the first state - ** is all rules which have the start symbol as their - ** left-hand side */ - for(rp=sp->rule; rp; rp=rp->nextlhs){ - struct config *newcfp; - newcfp = Configlist_addbasis(rp,0); - SetAdd(newcfp->fws,0); - } - - /* Compute the first state. All other states will be - ** computed automatically during the computation of the first one. - ** The returned pointer to the first state is not used. */ - (void)getstate(lemp); - return; -} - -/* Return a pointer to a state which is described by the configuration -** list which has been built from calls to Configlist_add. -*/ -PRIVATE void buildshifts(/* struct lemon *, struct state * */); /* Forwd ref */ -PRIVATE struct state *getstate(lemp) -struct lemon *lemp; -{ - struct config *cfp, *bp; - struct state *stp; - - /* Extract the sorted basis of the new state. The basis was constructed - ** by prior calls to "Configlist_addbasis()". */ - Configlist_sortbasis(); - bp = Configlist_basis(); - - /* Get a state with the same basis */ - stp = State_find(bp); - if( stp ){ - /* A state with the same basis already exists! Copy all the follow-set - ** propagation links from the state under construction into the - ** preexisting state, then return a pointer to the preexisting state */ - struct config *x, *y; - for(x=bp, y=stp->bp; x && y; x=x->bp, y=y->bp){ - Plink_copy(&y->bplp,x->bplp); - Plink_delete(x->fplp); - x->fplp = x->bplp = 0; - } - cfp = Configlist_return(); - Configlist_eat(cfp); - }else{ - /* This really is a new state. Construct all the details */ - Configlist_closure(lemp); /* Compute the configuration closure */ - Configlist_sort(); /* Sort the configuration closure */ - cfp = Configlist_return(); /* Get a pointer to the config list */ - stp = State_new(); /* A new state structure */ - MemoryCheck(stp); - stp->bp = bp; /* Remember the configuration basis */ - stp->cfp = cfp; /* Remember the configuration closure */ - stp->index = lemp->nstate++; /* Every state gets a sequence number */ - stp->ap = 0; /* No actions, yet. */ - State_insert(stp,stp->bp); /* Add to the state table */ - buildshifts(lemp,stp); /* Recursively compute successor states */ - } - return stp; -} - -/* Construct all successor states to the given state. A "successor" -** state is any state which can be reached by a shift action. -*/ -PRIVATE void buildshifts(lemp,stp) -struct lemon *lemp; -struct state *stp; /* The state from which successors are computed */ -{ - struct config *cfp; /* For looping thru the config closure of "stp" */ - struct config *bcfp; /* For the inner loop on config closure of "stp" */ - struct config *new; /* */ - struct symbol *sp; /* Symbol following the dot in configuration "cfp" */ - struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ - struct state *newstp; /* A pointer to a successor state */ - - /* Each configuration becomes complete after it contibutes to a successor - ** state. Initially, all configurations are incomplete */ - for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE; - - /* Loop through all configurations of the state "stp" */ - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; /* Already used by inner loop */ - if( cfp->dot>=cfp->rp->nrhs ) continue; /* Can't shift this config */ - Configlist_reset(); /* Reset the new config set */ - sp = cfp->rp->rhs[cfp->dot]; /* Symbol after the dot */ - - /* For every configuration in the state "stp" which has the symbol "sp" - ** following its dot, add the same configuration to the basis set under - ** construction but with the dot shifted one symbol to the right. */ - for(bcfp=cfp; bcfp; bcfp=bcfp->next){ - if( bcfp->status==COMPLETE ) continue; /* Already used */ - if( bcfp->dot>=bcfp->rp->nrhs ) continue; /* Can't shift this one */ - bsp = bcfp->rp->rhs[bcfp->dot]; /* Get symbol after dot */ - if( bsp!=sp ) continue; /* Must be same as for "cfp" */ - bcfp->status = COMPLETE; /* Mark this config as used */ - new = Configlist_addbasis(bcfp->rp,bcfp->dot+1); - Plink_add(&new->bplp,bcfp); - } - - /* Get a pointer to the state described by the basis configuration set - ** constructed in the preceding loop */ - newstp = getstate(lemp); - - /* The state "newstp" is reached from the state "stp" by a shift action - ** on the symbol "sp" */ - Action_add(&stp->ap,SHIFT,sp,(char *)newstp); - } -} - -/* -** Construct the propagation links -*/ -void FindLinks(lemp) -struct lemon *lemp; -{ - int i; - struct config *cfp, *other; - struct state *stp; - struct plink *plp; - - /* Housekeeping detail: - ** Add to every propagate link a pointer back to the state to - ** which the link is attached. */ - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - cfp->stp = stp; - } - } - - /* Convert all backlinks into forward links. Only the forward - ** links are used in the follow-set computation. */ - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - for(plp=cfp->bplp; plp; plp=plp->next){ - other = plp->cfp; - Plink_add(&other->fplp,cfp); - } - } - } -} - -/* Compute all followsets. -** -** A followset is the set of all symbols which can come immediately -** after a configuration. -*/ -void FindFollowSets(lemp) -struct lemon *lemp; -{ - int i; - struct config *cfp; - struct plink *plp; - int progress; - int change; - - for(i=0; instate; i++){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - cfp->status = INCOMPLETE; - } - } - - do{ - progress = 0; - for(i=0; instate; i++){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; - for(plp=cfp->fplp; plp; plp=plp->next){ - change = SetUnion(plp->cfp->fws,cfp->fws); - if( change ){ - plp->cfp->status = INCOMPLETE; - progress = 1; - } - } - cfp->status = COMPLETE; - } - } - }while( progress ); -} - -static int resolve_conflict(); - -/* Compute the reduce actions, and resolve conflicts. -*/ -void FindActions(lemp) -struct lemon *lemp; -{ - int i,j; - struct config *cfp; - struct state *stp; - struct symbol *sp; - struct rule *rp; - - /* Add all of the reduce actions - ** A reduce action is added for each element of the followset of - ** a configuration which has its dot at the extreme right. - */ - for(i=0; instate; i++){ /* Loop over all states */ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */ - if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */ - for(j=0; jnterminal; j++){ - if( SetFind(cfp->fws,j) ){ - /* Add a reduce action to the state "stp" which will reduce by the - ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */ - Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); - } - } - } - } - } - - /* Add the accepting token */ - if( lemp->start ){ - sp = Symbol_find(lemp->start); - if( sp==0 ) sp = lemp->rule->lhs; - }else{ - sp = lemp->rule->lhs; - } - /* Add to the first state (which is always the starting state of the - ** finite state machine) an action to ACCEPT if the lookahead is the - ** start nonterminal. */ - Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0); - - /* Resolve conflicts */ - for(i=0; instate; i++){ - struct action *ap, *nap; - struct state *stp; - stp = lemp->sorted[i]; - assert( stp->ap ); - stp->ap = Action_sort(stp->ap); - for(ap=stp->ap; ap && ap->next; ap=ap->next){ - for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){ - /* The two actions "ap" and "nap" have the same lookahead. - ** Figure out which one should be used */ - lemp->nconflict += resolve_conflict(ap,nap,lemp->errsym); - } - } - } - - /* Report an error for each rule that can never be reduced. */ - for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = B_FALSE; - for(i=0; instate; i++){ - struct action *ap; - for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ - if( ap->type==REDUCE ) ap->x.rp->canReduce = B_TRUE; - } - } - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->canReduce ) continue; - ErrorMsg(lemp->filename,rp->ruleline,"This rule can not be reduced.\n"); - lemp->errorcnt++; - } -} - -/* Resolve a conflict between the two given actions. If the -** conflict can't be resolve, return non-zero. -** -** NO LONGER TRUE: -** To resolve a conflict, first look to see if either action -** is on an error rule. In that case, take the action which -** is not associated with the error rule. If neither or both -** actions are associated with an error rule, then try to -** use precedence to resolve the conflict. -** -** If either action is a SHIFT, then it must be apx. This -** function won't work if apx->type==REDUCE and apy->type==SHIFT. -*/ -static int resolve_conflict(apx,apy,errsym) -struct action *apx; -struct action *apy; -struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */ -{ - struct symbol *spx, *spy; - int errcnt = 0; - assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */ - if( apx->type==SHIFT && apy->type==REDUCE ){ - spx = apx->sp; - spy = apy->x.rp->precsym; - if( spy==0 || spx->prec<0 || spy->prec<0 ){ - /* Not enough precedence information. */ - apy->type = CONFLICT; - errcnt++; - }else if( spx->prec>spy->prec ){ /* Lower precedence wins */ - apy->type = RD_RESOLVED; - }else if( spx->precprec ){ - apx->type = SH_RESOLVED; - }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */ - apy->type = RD_RESOLVED; /* associativity */ - }else if( spx->prec==spy->prec && spx->assoc==LEFT ){ /* to break tie */ - apx->type = SH_RESOLVED; - }else{ - assert( spx->prec==spy->prec && spx->assoc==NONE ); - apy->type = CONFLICT; - errcnt++; - } - }else if( apx->type==REDUCE && apy->type==REDUCE ){ - spx = apx->x.rp->precsym; - spy = apy->x.rp->precsym; - if( spx==0 || spy==0 || spx->prec<0 || - spy->prec<0 || spx->prec==spy->prec ){ - apy->type = CONFLICT; - errcnt++; - }else if( spx->prec>spy->prec ){ - apy->type = RD_RESOLVED; - }else if( spx->precprec ){ - apx->type = RD_RESOLVED; - } - }else{ - assert( - apx->type==SH_RESOLVED || - apx->type==RD_RESOLVED || - apx->type==CONFLICT || - apy->type==SH_RESOLVED || - apy->type==RD_RESOLVED || - apy->type==CONFLICT - ); - /* The REDUCE/SHIFT case cannot happen because SHIFTs come before - ** REDUCEs on the list. If we reach this point it must be because - ** the parser conflict had already been resolved. */ - } - return errcnt; -} -/********************* From the file "configlist.c" *************************/ -/* -** Routines to processing a configuration list and building a state -** in the LEMON parser generator. -*/ - -static struct config *freelist = 0; /* List of free configurations */ -static struct config *current = 0; /* Top of list of configurations */ -static struct config **currentend = 0; /* Last on list of configs */ -static struct config *basis = 0; /* Top of list of basis configs */ -static struct config **basisend = 0; /* End of list of basis configs */ - -/* Return a pointer to a new configuration */ -PRIVATE struct config *newconfig(){ - struct config *new; - if( freelist==0 ){ - int i; - int amt = 3; - freelist = (struct config *)malloc( sizeof(struct config)*amt ); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new configuration."); - exit(1); - } - for(i=0; inext; - return new; -} - -/* The configuration "old" is no longer used */ -PRIVATE void deleteconfig(old) -struct config *old; -{ - old->next = freelist; - freelist = old; -} - -/* Initialized the configuration list builder */ -void Configlist_init(){ - current = 0; - currentend = ¤t; - basis = 0; - basisend = &basis; - Configtable_init(); - return; -} - -/* Initialized the configuration list builder */ -void Configlist_reset(){ - current = 0; - currentend = ¤t; - basis = 0; - basisend = &basis; - Configtable_clear(0); - return; -} - -/* Add another configuration to the configuration list */ -struct config *Configlist_add(rp,dot) -struct rule *rp; /* The rule */ -int dot; /* Index into the RHS of the rule where the dot goes */ -{ - struct config *cfp, model; - - assert( currentend!=0 ); - model.rp = rp; - model.dot = dot; - cfp = Configtable_find(&model); - if( cfp==0 ){ - cfp = newconfig(); - cfp->rp = rp; - cfp->dot = dot; - cfp->fws = SetNew(); - cfp->stp = 0; - cfp->fplp = cfp->bplp = 0; - cfp->next = 0; - cfp->bp = 0; - *currentend = cfp; - currentend = &cfp->next; - Configtable_insert(cfp); - } - return cfp; -} - -/* Add a basis configuration to the configuration list */ -struct config *Configlist_addbasis(rp,dot) -struct rule *rp; -int dot; -{ - struct config *cfp, model; - - assert( basisend!=0 ); - assert( currentend!=0 ); - model.rp = rp; - model.dot = dot; - cfp = Configtable_find(&model); - if( cfp==0 ){ - cfp = newconfig(); - cfp->rp = rp; - cfp->dot = dot; - cfp->fws = SetNew(); - cfp->stp = 0; - cfp->fplp = cfp->bplp = 0; - cfp->next = 0; - cfp->bp = 0; - *currentend = cfp; - currentend = &cfp->next; - *basisend = cfp; - basisend = &cfp->bp; - Configtable_insert(cfp); - } - return cfp; -} - -/* Compute the closure of the configuration list */ -void Configlist_closure(lemp) -struct lemon *lemp; -{ - struct config *cfp, *newcfp; - struct rule *rp, *newrp; - struct symbol *sp, *xsp; - int i, dot; - - assert( currentend!=0 ); - for(cfp=current; cfp; cfp=cfp->next){ - rp = cfp->rp; - dot = cfp->dot; - if( dot>=rp->nrhs ) continue; - sp = rp->rhs[dot]; - if( sp->type==NONTERMINAL ){ - if( sp->rule==0 && sp!=lemp->errsym ){ - ErrorMsg(lemp->filename,rp->line,"Nonterminal \"%s\" has no rules.", - sp->name); - lemp->errorcnt++; - } - for(newrp=sp->rule; newrp; newrp=newrp->nextlhs){ - newcfp = Configlist_add(newrp,0); - for(i=dot+1; inrhs; i++){ - xsp = rp->rhs[i]; - if( xsp->type==TERMINAL ){ - SetAdd(newcfp->fws,xsp->index); - break; - }else{ - SetUnion(newcfp->fws,xsp->firstset); - if( xsp->lambda==B_FALSE ) break; - } - } - if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp); - } - } - } - return; -} - -/* Sort the configuration list */ -void Configlist_sort(){ - current = (struct config *)msort((char *)current,(char **)&(current->next),Configcmp); - currentend = 0; - return; -} - -/* Sort the basis configuration list */ -void Configlist_sortbasis(){ - basis = (struct config *)msort((char *)current,(char **)&(current->bp),Configcmp); - basisend = 0; - return; -} - -/* Return a pointer to the head of the configuration list and -** reset the list */ -struct config *Configlist_return(){ - struct config *old; - old = current; - current = 0; - currentend = 0; - return old; -} - -/* Return a pointer to the head of the configuration list and -** reset the list */ -struct config *Configlist_basis(){ - struct config *old; - old = basis; - basis = 0; - basisend = 0; - return old; -} - -/* Free all elements of the given configuration list */ -void Configlist_eat(cfp) -struct config *cfp; -{ - struct config *nextcfp; - for(; cfp; cfp=nextcfp){ - nextcfp = cfp->next; - assert( cfp->fplp==0 ); - assert( cfp->bplp==0 ); - if( cfp->fws ) SetFree(cfp->fws); - deleteconfig(cfp); - } - return; -} -/***************** From the file "error.c" *********************************/ -/* -** Code for printing error message. -*/ - -/* Find a good place to break "msg" so that its length is at least "min" -** but no more than "max". Make the point as close to max as possible. -*/ -static int findbreak(msg,min,max) -char *msg; -int min; -int max; -{ - int i,spot; - char c; - for(i=spot=min; i<=max; i++){ - c = msg[i]; - if( c=='\t' ) msg[i] = ' '; - if( c=='\n' ){ msg[i] = ' '; spot = i; break; } - if( c==0 ){ spot = i; break; } - if( c=='-' && i0 ){ - sprintf(prefix,"%.*s:%d: ",PREFIXLIMIT-10,filename,lineno); - }else{ - sprintf(prefix,"%.*s: ",PREFIXLIMIT-10,filename); - } - prefixsize = strlen(prefix); - availablewidth = LINEWIDTH - prefixsize; - - /* Generate the error message */ - vsprintf(errmsg,format,ap); - va_end(ap); - errmsgsize = strlen(errmsg); - /* Remove trailing '\n's from the error message. */ - while( errmsgsize>0 && errmsg[errmsgsize-1]=='\n' ){ - errmsg[--errmsgsize] = 0; - } - - /* Print the error message */ - base = 0; - while( errmsg[base]!=0 ){ - end = restart = findbreak(&errmsg[base],0,availablewidth); - restart += base; - while( errmsg[restart]==' ' ) restart++; - fprintf(stdout,"%s%.*s\n",prefix,end,&errmsg[base]); - base = restart; - } -} -/**************** From the file "main.c" ************************************/ -/* -** Main program file for the LEMON parser generator. -*/ - -/* Report an out-of-memory condition and abort. This function -** is used mostly by the "MemoryCheck" macro in struct.h -*/ -void memory_error(){ - fprintf(stderr,"Out of memory. Aborting...\n"); - exit(1); -} - -static int nDefine = 0; /* Number of -D options on the command line */ -static char **azDefine = 0; /* Name of the -D macros */ - -/* This routine is called with the argument to each -D command-line option. -** Add the macro defined to the azDefine array. -*/ -static void handle_D_option(char *z){ - char **paz; - nDefine++; - azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine); - if( azDefine==0 ){ - fprintf(stderr,"out of memory\n"); - exit(1); - } - paz = &azDefine[nDefine-1]; - *paz = malloc( strlen(z)+1 ); - if( *paz==0 ){ - fprintf(stderr,"out of memory\n"); - exit(1); - } - strcpy(*paz, z); - for(z=*paz; *z && *z!='='; z++){} - *z = 0; -} - - -/* The main program. Parse the command line and do it... */ -int main(argc,argv) -int argc; -char **argv; -{ - static int version = 0; - static int rpflag = 0; - static int basisflag = 0; - static int compress = 0; - static int quiet = 0; - static int statistics = 0; - static int mhflag = 0; - static struct s_options options[] = { - {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."}, - {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."}, - {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."}, - {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."}, - {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file"}, - {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."}, - {OPT_FLAG, "s", (char*)&statistics, - "Print parser stats to standard output."}, - {OPT_FLAG, "x", (char*)&version, "Print the version number."}, - {OPT_FLAG,0,0,0} - }; - int i; - struct lemon lem; - - OptInit(argv,options,stderr); - if( version ){ - printf("Lemon version 1.0\n"); - exit(0); - } - if( OptNArgs()!=1 ){ - fprintf(stderr,"Exactly one filename argument is required.\n"); - exit(1); - } - lem.errorcnt = 0; - - /* Initialize the machine */ - Strsafe_init(); - Symbol_init(); - State_init(); - lem.argv0 = argv[0]; - lem.filename = OptArg(0); - lem.basisflag = basisflag; - lem.has_fallback = 0; - lem.nconflict = 0; - lem.name = lem.include = lem.arg = lem.tokentype = lem.start = 0; - lem.vartype = 0; - lem.stacksize = 0; - lem.error = lem.overflow = lem.failure = lem.accept = lem.tokendest = - lem.tokenprefix = lem.outname = lem.extracode = 0; - lem.vardest = 0; - lem.tablesize = 0; - Symbol_new("$"); - lem.errsym = Symbol_new("error"); - - /* Parse the input file */ - Parse(&lem); - if( lem.errorcnt ) exit(lem.errorcnt); - if( lem.rule==0 ){ - fprintf(stderr,"Empty grammar.\n"); - exit(1); - } - - /* Count and index the symbols of the grammar */ - lem.nsymbol = Symbol_count(); - Symbol_new("{default}"); - lem.symbols = Symbol_arrayof(); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), - (int(*)())Symbolcmpp); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - for(i=1; isupper(lem.symbols[i]->name[0]); i++); - lem.nterminal = i; - - /* Generate a reprint of the grammar, if requested on the command line */ - if( rpflag ){ - Reprint(&lem); - }else{ - /* Initialize the size for all follow and first sets */ - SetSize(lem.nterminal); - - /* Find the precedence for every production rule (that has one) */ - FindRulePrecedences(&lem); - - /* Compute the lambda-nonterminals and the first-sets for every - ** nonterminal */ - FindFirstSets(&lem); - - /* Compute all LR(0) states. Also record follow-set propagation - ** links so that the follow-set can be computed later */ - lem.nstate = 0; - FindStates(&lem); - lem.sorted = State_arrayof(); - - /* Tie up loose ends on the propagation links */ - FindLinks(&lem); - - /* Compute the follow set of every reducible configuration */ - FindFollowSets(&lem); - - /* Compute the action tables */ - FindActions(&lem); - - /* Compress the action tables */ - if( compress==0 ) CompressTables(&lem); - - /* Generate a report of the parser generated. (the "y.output" file) */ - if( !quiet ) ReportOutput(&lem); - - /* Generate the source code for the parser */ - ReportTable(&lem, mhflag); - - /* Produce a header file for use by the scanner. (This step is - ** omitted if the "-m" option is used because makeheaders will - ** generate the file for us.) */ - if( !mhflag ) ReportHeader(&lem); - } - if( statistics ){ - printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n", - lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule); - printf(" %d states, %d parser table entries, %d conflicts\n", - lem.nstate, lem.tablesize, lem.nconflict); - } - if( lem.nconflict ){ - fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict); - } - exit(lem.errorcnt + lem.nconflict); - return (lem.errorcnt + lem.nconflict); -} -/******************** From the file "msort.c" *******************************/ -/* -** A generic merge-sort program. -** -** USAGE: -** Let "ptr" be a pointer to some structure which is at the head of -** a null-terminated list. Then to sort the list call: -** -** ptr = msort(ptr,&(ptr->next),cmpfnc); -** -** In the above, "cmpfnc" is a pointer to a function which compares -** two instances of the structure and returns an integer, as in -** strcmp. The second argument is a pointer to the pointer to the -** second element of the linked list. This address is used to compute -** the offset to the "next" field within the structure. The offset to -** the "next" field must be constant for all structures in the list. -** -** The function returns a new pointer which is the head of the list -** after sorting. -** -** ALGORITHM: -** Merge-sort. -*/ - -/* -** Return a pointer to the next structure in the linked list. -*/ -#define NEXT(A) (*(char**)(((unsigned long)A)+offset)) - -/* -** Inputs: -** a: A sorted, null-terminated linked list. (May be null). -** b: A sorted, null-terminated linked list. (May be null). -** cmp: A pointer to the comparison function. -** offset: Offset in the structure to the "next" field. -** -** Return Value: -** A pointer to the head of a sorted list containing the elements -** of both a and b. -** -** Side effects: -** The "next" pointers for elements in the lists a and b are -** changed. -*/ -static char *merge(a,b,cmp,offset) -char *a; -char *b; -int (*cmp)(); -int offset; -{ - char *ptr, *head; - - if( a==0 ){ - head = b; - }else if( b==0 ){ - head = a; - }else{ - if( (*cmp)(a,b)<0 ){ - ptr = a; - a = NEXT(a); - }else{ - ptr = b; - b = NEXT(b); - } - head = ptr; - while( a && b ){ - if( (*cmp)(a,b)<0 ){ - NEXT(ptr) = a; - ptr = a; - a = NEXT(a); - }else{ - NEXT(ptr) = b; - ptr = b; - b = NEXT(b); - } - } - if( a ) NEXT(ptr) = a; - else NEXT(ptr) = b; - } - return head; -} - -/* -** Inputs: -** list: Pointer to a singly-linked list of structures. -** next: Pointer to pointer to the second element of the list. -** cmp: A comparison function. -** -** Return Value: -** A pointer to the head of a sorted list containing the elements -** orginally in list. -** -** Side effects: -** The "next" pointers for elements in list are changed. -*/ -#define LISTSIZE 30 -char *msort(list,next,cmp) -char *list; -char **next; -int (*cmp)(); -{ - unsigned long offset; - char *ep; - char *set[LISTSIZE]; - int i; - offset = (unsigned long)next - (unsigned long)list; - for(i=0; istate = WAITING_FOR_DECL_KEYWORD; - }else if( islower(x[0]) ){ - psp->lhs = Symbol_new(x); - psp->nrhs = 0; - psp->lhsalias = 0; - psp->state = WAITING_FOR_ARROW; - }else if( x[0]=='{' ){ - if( psp->prevrule==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"There is not prior rule opon which to attach the code \ -fragment which begins on this line."); - psp->errorcnt++; - }else if( psp->prevrule->code!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"Code fragment beginning on this line is not the first \ -to follow the previous rule."); - psp->errorcnt++; - }else{ - psp->prevrule->line = psp->tokenlineno; - psp->prevrule->code = &x[1]; - } - }else if( x[0]=='[' ){ - psp->state = PRECEDENCE_MARK_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Token \"%s\" should be either \"%%\" or a nonterminal name.", - x); - psp->errorcnt++; - } - break; - case PRECEDENCE_MARK_1: - if( !isupper(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "The precedence symbol must be a terminal."); - psp->errorcnt++; - }else if( psp->prevrule==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "There is no prior rule to assign precedence \"[%s]\".",x); - psp->errorcnt++; - }else if( psp->prevrule->precsym!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"Precedence mark on this line is not the first \ -to follow the previous rule."); - psp->errorcnt++; - }else{ - psp->prevrule->precsym = Symbol_new(x); - } - psp->state = PRECEDENCE_MARK_2; - break; - case PRECEDENCE_MARK_2: - if( x[0]!=']' ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \"]\" on precedence mark."); - psp->errorcnt++; - } - psp->state = WAITING_FOR_DECL_OR_RULE; - break; - case WAITING_FOR_ARROW: - if( x[0]==':' && x[1]==':' && x[2]=='=' ){ - psp->state = IN_RHS; - }else if( x[0]=='(' ){ - psp->state = LHS_ALIAS_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Expected to see a \":\" following the LHS symbol \"%s\".", - psp->lhs->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_1: - if( isalpha(x[0]) ){ - psp->lhsalias = x; - psp->state = LHS_ALIAS_2; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "\"%s\" is not a valid alias for the LHS \"%s\"\n", - x,psp->lhs->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_2: - if( x[0]==')' ){ - psp->state = LHS_ALIAS_3; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_3: - if( x[0]==':' && x[1]==':' && x[2]=='=' ){ - psp->state = IN_RHS; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \"->\" following: \"%s(%s)\".", - psp->lhs->name,psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case IN_RHS: - if( x[0]=='.' ){ - struct rule *rp; - rp = (struct rule *)malloc( sizeof(struct rule) + - sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs ); - if( rp==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Can't allocate enough memory for this rule."); - psp->errorcnt++; - psp->prevrule = 0; - }else{ - int i; - rp->ruleline = psp->tokenlineno; - rp->rhs = (struct symbol**)&rp[1]; - rp->rhsalias = (char**)&(rp->rhs[psp->nrhs]); - for(i=0; inrhs; i++){ - rp->rhs[i] = psp->rhs[i]; - rp->rhsalias[i] = psp->alias[i]; - } - rp->lhs = psp->lhs; - rp->lhsalias = psp->lhsalias; - rp->nrhs = psp->nrhs; - rp->code = 0; - rp->precsym = 0; - rp->index = psp->gp->nrule++; - rp->nextlhs = rp->lhs->rule; - rp->lhs->rule = rp; - rp->next = 0; - if( psp->firstrule==0 ){ - psp->firstrule = psp->lastrule = rp; - }else{ - psp->lastrule->next = rp; - psp->lastrule = rp; - } - psp->prevrule = rp; - } - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isalpha(x[0]) ){ - if( psp->nrhs>=MAXRHS ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Too many symbol on RHS or rule beginning at \"%s\".", - x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - }else{ - psp->rhs[psp->nrhs] = Symbol_new(x); - psp->alias[psp->nrhs] = 0; - psp->nrhs++; - } - }else if( x[0]=='(' && psp->nrhs>0 ){ - psp->state = RHS_ALIAS_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal character on RHS of rule: \"%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case RHS_ALIAS_1: - if( isalpha(x[0]) ){ - psp->alias[psp->nrhs-1] = x; - psp->state = RHS_ALIAS_2; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "\"%s\" is not a valid alias for the RHS symbol \"%s\"\n", - x,psp->rhs[psp->nrhs-1]->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case RHS_ALIAS_2: - if( x[0]==')' ){ - psp->state = IN_RHS; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case WAITING_FOR_DECL_KEYWORD: - if( isalpha(x[0]) ){ - psp->declkeyword = x; - psp->declargslot = 0; - psp->decllnslot = 0; - psp->state = WAITING_FOR_DECL_ARG; - if( strcmp(x,"name")==0 ){ - psp->declargslot = &(psp->gp->name); - }else if( strcmp(x,"include")==0 ){ - psp->declargslot = &(psp->gp->include); - psp->decllnslot = &psp->gp->includeln; - }else if( strcmp(x,"code")==0 ){ - psp->declargslot = &(psp->gp->extracode); - psp->decllnslot = &psp->gp->extracodeln; - }else if( strcmp(x,"token_destructor")==0 ){ - psp->declargslot = &psp->gp->tokendest; - psp->decllnslot = &psp->gp->tokendestln; - }else if( strcmp(x,"default_destructor")==0 ){ - psp->declargslot = &psp->gp->vardest; - psp->decllnslot = &psp->gp->vardestln; - }else if( strcmp(x,"token_prefix")==0 ){ - psp->declargslot = &psp->gp->tokenprefix; - }else if( strcmp(x,"syntax_error")==0 ){ - psp->declargslot = &(psp->gp->error); - psp->decllnslot = &psp->gp->errorln; - }else if( strcmp(x,"parse_accept")==0 ){ - psp->declargslot = &(psp->gp->accept); - psp->decllnslot = &psp->gp->acceptln; - }else if( strcmp(x,"parse_failure")==0 ){ - psp->declargslot = &(psp->gp->failure); - psp->decllnslot = &psp->gp->failureln; - }else if( strcmp(x,"stack_overflow")==0 ){ - psp->declargslot = &(psp->gp->overflow); - psp->decllnslot = &psp->gp->overflowln; - }else if( strcmp(x,"extra_argument")==0 ){ - psp->declargslot = &(psp->gp->arg); - }else if( strcmp(x,"token_type")==0 ){ - psp->declargslot = &(psp->gp->tokentype); - }else if( strcmp(x,"default_type")==0 ){ - psp->declargslot = &(psp->gp->vartype); - }else if( strcmp(x,"stack_size")==0 ){ - psp->declargslot = &(psp->gp->stacksize); - }else if( strcmp(x,"start_symbol")==0 ){ - psp->declargslot = &(psp->gp->start); - }else if( strcmp(x,"left")==0 ){ - psp->preccounter++; - psp->declassoc = LEFT; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"right")==0 ){ - psp->preccounter++; - psp->declassoc = RIGHT; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"nonassoc")==0 ){ - psp->preccounter++; - psp->declassoc = NONE; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"destructor")==0 ){ - psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL; - }else if( strcmp(x,"type")==0 ){ - psp->state = WAITING_FOR_DATATYPE_SYMBOL; - }else if( strcmp(x,"fallback")==0 ){ - psp->fallback = 0; - psp->state = WAITING_FOR_FALLBACK_ID; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Unknown declaration keyword: \"%%%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal declaration keyword: \"%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - break; - case WAITING_FOR_DESTRUCTOR_SYMBOL: - if( !isalpha(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol name missing after %destructor keyword"); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - struct symbol *sp = Symbol_new(x); - psp->declargslot = &sp->destructor; - psp->decllnslot = &sp->destructorln; - psp->state = WAITING_FOR_DECL_ARG; - } - break; - case WAITING_FOR_DATATYPE_SYMBOL: - if( !isalpha(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol name missing after %destructor keyword"); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - struct symbol *sp = Symbol_new(x); - psp->declargslot = &sp->datatype; - psp->decllnslot = 0; - psp->state = WAITING_FOR_DECL_ARG; - } - break; - case WAITING_FOR_PRECEDENCE_SYMBOL: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isupper(x[0]) ){ - struct symbol *sp; - sp = Symbol_new(x); - if( sp->prec>=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol \"%s\" has already be given a precedence.",x); - psp->errorcnt++; - }else{ - sp->prec = psp->preccounter; - sp->assoc = psp->declassoc; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Can't assign a precedence to \"%s\".",x); - psp->errorcnt++; - } - break; - case WAITING_FOR_DECL_ARG: - if( (x[0]=='{' || x[0]=='\"' || isalnum(x[0])) ){ - if( *(psp->declargslot)!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "The argument \"%s\" to declaration \"%%%s\" is not the first.", - x[0]=='\"' ? &x[1] : x,psp->declkeyword); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - *(psp->declargslot) = (x[0]=='\"' || x[0]=='{') ? &x[1] : x; - if( psp->decllnslot ) *psp->decllnslot = psp->tokenlineno; - psp->state = WAITING_FOR_DECL_OR_RULE; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal argument to %%%s: %s",psp->declkeyword,x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - break; - case WAITING_FOR_FALLBACK_ID: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( !isupper(x[0]) ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "%%fallback argument \"%s\" should be a token", x); - psp->errorcnt++; - }else{ - struct symbol *sp = Symbol_new(x); - if( psp->fallback==0 ){ - psp->fallback = sp; - }else if( sp->fallback ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "More than one fallback assigned to token %s", x); - psp->errorcnt++; - }else{ - sp->fallback = psp->fallback; - psp->gp->has_fallback = 1; - } - } - break; - case RESYNC_AFTER_RULE_ERROR: -/* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; -** break; */ - case RESYNC_AFTER_DECL_ERROR: - if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; - if( x[0]=='%' ) psp->state = WAITING_FOR_DECL_KEYWORD; - break; - } -} - -/* Run the proprocessor over the input file text. The global variables -** azDefine[0] through azDefine[nDefine-1] contains the names of all defined -** macros. This routine looks for "%ifdef" and "%ifndef" and "%endif" and -** comments them out. Text in between is also commented out as appropriate. -*/ -static void preprocess_input(char *z){ - int i, j, k, n; - int exclude = 0; - int start; - int lineno = 1; - int start_lineno; - for(i=0; z[i]; i++){ - if( z[i]=='\n' ) lineno++; - if( z[i]!='%' || (i>0 && z[i-1]!='\n') ) continue; - if( strncmp(&z[i],"%endif",6)==0 && isspace(z[i+6]) ){ - if( exclude ){ - exclude--; - if( exclude==0 ){ - for(j=start; jfilename; - ps.errorcnt = 0; - ps.state = INITIALIZE; - - /* Begin by reading the input file */ - fp = fopen(ps.filename,"rb"); - if( fp==0 ){ - ErrorMsg(ps.filename,0,"Can't open this file for reading."); - gp->errorcnt++; - return; - } - fseek(fp,0,2); - filesize = ftell(fp); - rewind(fp); - filebuf = (char *)malloc( filesize+1 ); - if( filebuf==0 ){ - ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", - filesize+1); - gp->errorcnt++; - return; - } - if( fread(filebuf,1,filesize,fp)!=filesize ){ - ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.", - filesize); - free(filebuf); - gp->errorcnt++; - return; - } - fclose(fp); - filebuf[filesize] = 0; - - /* Make an initial pass through the file to handle %ifdef and %ifndef */ - preprocess_input(filebuf); - - /* Now scan the text of the input file */ - lineno = 1; - for(cp=filebuf; (c= *cp)!=0; ){ - if( c=='\n' ) lineno++; /* Keep track of the line number */ - if( isspace(c) ){ cp++; continue; } /* Skip all white space */ - if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments */ - cp+=2; - while( (c= *cp)!=0 && c!='\n' ) cp++; - continue; - } - if( c=='/' && cp[1]=='*' ){ /* Skip C style comments */ - cp+=2; - while( (c= *cp)!=0 && (c!='/' || cp[-1]!='*') ){ - if( c=='\n' ) lineno++; - cp++; - } - if( c ) cp++; - continue; - } - ps.tokenstart = cp; /* Mark the beginning of the token */ - ps.tokenlineno = lineno; /* Linenumber on which token begins */ - if( c=='\"' ){ /* String literals */ - cp++; - while( (c= *cp)!=0 && c!='\"' ){ - if( c=='\n' ) lineno++; - cp++; - } - if( c==0 ){ - ErrorMsg(ps.filename,startline, -"String starting on this line is not terminated before the end of the file."); - ps.errorcnt++; - nextcp = cp; - }else{ - nextcp = cp+1; - } - }else if( c=='{' ){ /* A block of C code */ - int level; - cp++; - for(level=1; (c= *cp)!=0 && (level>1 || c!='}'); cp++){ - if( c=='\n' ) lineno++; - else if( c=='{' ) level++; - else if( c=='}' ) level--; - else if( c=='/' && cp[1]=='*' ){ /* Skip comments */ - int prevc; - cp = &cp[2]; - prevc = 0; - while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){ - if( c=='\n' ) lineno++; - prevc = c; - cp++; - } - }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */ - cp = &cp[2]; - while( (c= *cp)!=0 && c!='\n' ) cp++; - if( c ) lineno++; - }else if( c=='\'' || c=='\"' ){ /* String a character literals */ - int startchar, prevc; - startchar = c; - prevc = 0; - for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){ - if( c=='\n' ) lineno++; - if( prevc=='\\' ) prevc = 0; - else prevc = c; - } - } - } - if( c==0 ){ - ErrorMsg(ps.filename,ps.tokenlineno, -"C code starting on this line is not terminated before the end of the file."); - ps.errorcnt++; - nextcp = cp; - }else{ - nextcp = cp+1; - } - }else if( isalnum(c) ){ /* Identifiers */ - while( (c= *cp)!=0 && (isalnum(c) || c=='_') ) cp++; - nextcp = cp; - }else if( c==':' && cp[1]==':' && cp[2]=='=' ){ /* The operator "::=" */ - cp += 3; - nextcp = cp; - }else{ /* All other (one character) operators */ - cp++; - nextcp = cp; - } - c = *cp; - *cp = 0; /* Null terminate the token */ - parseonetoken(&ps); /* Parse the token */ - *cp = c; /* Restore the buffer */ - cp = nextcp; - } - free(filebuf); /* Release the buffer after parsing */ - gp->rule = ps.firstrule; - gp->errorcnt = ps.errorcnt; -} -/*************************** From the file "plink.c" *********************/ -/* -** Routines processing configuration follow-set propagation links -** in the LEMON parser generator. -*/ -static struct plink *plink_freelist = 0; - -/* Allocate a new plink */ -struct plink *Plink_new(){ - struct plink *new; - - if( plink_freelist==0 ){ - int i; - int amt = 100; - plink_freelist = (struct plink *)malloc( sizeof(struct plink)*amt ); - if( plink_freelist==0 ){ - fprintf(stderr, - "Unable to allocate memory for a new follow-set propagation link.\n"); - exit(1); - } - for(i=0; inext; - return new; -} - -/* Add a plink to a plink list */ -void Plink_add(plpp,cfp) -struct plink **plpp; -struct config *cfp; -{ - struct plink *new; - new = Plink_new(); - new->next = *plpp; - *plpp = new; - new->cfp = cfp; -} - -/* Transfer every plink on the list "from" to the list "to" */ -void Plink_copy(to,from) -struct plink **to; -struct plink *from; -{ - struct plink *nextpl; - while( from ){ - nextpl = from->next; - from->next = *to; - *to = from; - from = nextpl; - } -} - -/* Delete every plink on the list */ -void Plink_delete(plp) -struct plink *plp; -{ - struct plink *nextpl; - - while( plp ){ - nextpl = plp->next; - plp->next = plink_freelist; - plink_freelist = plp; - plp = nextpl; - } -} -/*********************** From the file "report.c" **************************/ -/* -** Procedures for generating reports and tables in the LEMON parser generator. -*/ - -/* Generate a filename with the given suffix. Space to hold the -** name comes from malloc() and must be freed by the calling -** function. -*/ -PRIVATE char *file_makename(lemp,suffix) -struct lemon *lemp; -char *suffix; -{ - char *name; - char *cp; - - name = malloc( strlen(lemp->filename) + strlen(suffix) + 5 ); - if( name==0 ){ - fprintf(stderr,"Can't allocate space for a filename.\n"); - exit(1); - } - strcpy(name,lemp->filename); - cp = strrchr(name,'.'); - if( cp ) *cp = 0; - strcat(name,suffix); - return name; -} - -/* Open a file with a name based on the name of the input file, -** but with a different (specified) suffix, and return a pointer -** to the stream */ -PRIVATE FILE *file_open(lemp,suffix,mode) -struct lemon *lemp; -char *suffix; -char *mode; -{ - FILE *fp; - - if( lemp->outname ) free(lemp->outname); - lemp->outname = file_makename(lemp, suffix); - fp = fopen(lemp->outname,mode); - if( fp==0 && *mode=='w' ){ - fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname); - lemp->errorcnt++; - return 0; - } - return fp; -} - -/* Duplicate the input file without comments and without actions -** on rules */ -void Reprint(lemp) -struct lemon *lemp; -{ - struct rule *rp; - struct symbol *sp; - int i, j, maxlen, len, ncolumns, skip; - printf("// Reprint of input file \"%s\".\n// Symbols:\n",lemp->filename); - maxlen = 10; - for(i=0; insymbol; i++){ - sp = lemp->symbols[i]; - len = strlen(sp->name); - if( len>maxlen ) maxlen = len; - } - ncolumns = 76/(maxlen+5); - if( ncolumns<1 ) ncolumns = 1; - skip = (lemp->nsymbol + ncolumns - 1)/ncolumns; - for(i=0; insymbol; j+=skip){ - sp = lemp->symbols[j]; - assert( sp->index==j ); - printf(" %3d %-*.*s",j,maxlen,maxlen,sp->name); - } - printf("\n"); - } - for(rp=lemp->rule; rp; rp=rp->next){ - printf("%s",rp->lhs->name); -/* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */ - printf(" ::="); - for(i=0; inrhs; i++){ - printf(" %s",rp->rhs[i]->name); -/* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ - } - printf("."); - if( rp->precsym ) printf(" [%s]",rp->precsym->name); -/* if( rp->code ) printf("\n %s",rp->code); */ - printf("\n"); - } -} - -void ConfigPrint(fp,cfp) -FILE *fp; -struct config *cfp; -{ - struct rule *rp; - int i; - rp = cfp->rp; - fprintf(fp,"%s ::=",rp->lhs->name); - for(i=0; i<=rp->nrhs; i++){ - if( i==cfp->dot ) fprintf(fp," *"); - if( i==rp->nrhs ) break; - fprintf(fp," %s",rp->rhs[i]->name); - } -} - -/* #define TEST */ -#ifdef TEST -/* Print a set */ -PRIVATE void SetPrint(out,set,lemp) -FILE *out; -char *set; -struct lemon *lemp; -{ - int i; - char *spacer; - spacer = ""; - fprintf(out,"%12s[",""); - for(i=0; interminal; i++){ - if( SetFind(set,i) ){ - fprintf(out,"%s%s",spacer,lemp->symbols[i]->name); - spacer = " "; - } - } - fprintf(out,"]\n"); -} - -/* Print a plink chain */ -PRIVATE void PlinkPrint(out,plp,tag) -FILE *out; -struct plink *plp; -char *tag; -{ - while( plp ){ - fprintf(out,"%12s%s (state %2d) ","",tag,plp->cfp->stp->index); - ConfigPrint(out,plp->cfp); - fprintf(out,"\n"); - plp = plp->next; - } -} -#endif - -/* Print an action to the given file descriptor. Return FALSE if -** nothing was actually printed. -*/ -int PrintAction(struct action *ap, FILE *fp, int indent){ - int result = 1; - switch( ap->type ){ - case SHIFT: - fprintf(fp,"%*s shift %d",indent,ap->sp->name,ap->x.stp->index); - break; - case REDUCE: - fprintf(fp,"%*s reduce %d",indent,ap->sp->name,ap->x.rp->index); - break; - case ACCEPT: - fprintf(fp,"%*s accept",indent,ap->sp->name); - break; - case ERROR: - fprintf(fp,"%*s error",indent,ap->sp->name); - break; - case CONFLICT: - fprintf(fp,"%*s reduce %-3d ** Parsing conflict **", - indent,ap->sp->name,ap->x.rp->index); - break; - case SH_RESOLVED: - case RD_RESOLVED: - case NOT_USED: - result = 0; - break; - } - return result; -} - -/* Generate the "y.output" log file */ -void ReportOutput(lemp) -struct lemon *lemp; -{ - int i; - struct state *stp; - struct config *cfp; - struct action *ap; - FILE *fp; - - fp = file_open(lemp,".out","wb"); - if( fp==0 ) return; - fprintf(fp," \b"); - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - fprintf(fp,"State %d:\n",stp->index); - if( lemp->basisflag ) cfp=stp->bp; - else cfp=stp->cfp; - while( cfp ){ - char buf[20]; - if( cfp->dot==cfp->rp->nrhs ){ - sprintf(buf,"(%d)",cfp->rp->index); - fprintf(fp," %5s ",buf); - }else{ - fprintf(fp," "); - } - ConfigPrint(fp,cfp); - fprintf(fp,"\n"); -#ifdef TEST - SetPrint(fp,cfp->fws,lemp); - PlinkPrint(fp,cfp->fplp,"To "); - PlinkPrint(fp,cfp->bplp,"From"); -#endif - if( lemp->basisflag ) cfp=cfp->bp; - else cfp=cfp->next; - } - fprintf(fp,"\n"); - for(ap=stp->ap; ap; ap=ap->next){ - if( PrintAction(ap,fp,30) ) fprintf(fp,"\n"); - } - fprintf(fp,"\n"); - } - fclose(fp); - return; -} - -/* Search for the file "name" which is in the same directory as -** the exacutable */ -PRIVATE char *pathsearch(argv0,name,modemask) -char *argv0; -char *name; -int modemask; -{ - char *pathlist; - char *path,*cp; - char c; - extern int access(); - -#ifdef __WIN32__ - cp = strrchr(argv0,'\\'); -#else - cp = strrchr(argv0,'/'); -#endif - if( cp ){ - c = *cp; - *cp = 0; - path = (char *)malloc( strlen(argv0) + strlen(name) + 2 ); - if( path ) sprintf(path,"%s/%s",argv0,name); - *cp = c; - }else{ - extern char *getenv(); - pathlist = getenv("PATH"); - if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; - path = (char *)malloc( strlen(pathlist)+strlen(name)+2 ); - if( path!=0 ){ - while( *pathlist ){ - cp = strchr(pathlist,':'); - if( cp==0 ) cp = &pathlist[strlen(pathlist)]; - c = *cp; - *cp = 0; - sprintf(path,"%s/%s",pathlist,name); - *cp = c; - if( c==0 ) pathlist = ""; - else pathlist = &cp[1]; - if( access(path,modemask)==0 ) break; - } - } - } - return path; -} - -/* Given an action, compute the integer value for that action -** which is to be put in the action table of the generated machine. -** Return negative if no action should be generated. -*/ -PRIVATE int compute_action(lemp,ap) -struct lemon *lemp; -struct action *ap; -{ - int act; - switch( ap->type ){ - case SHIFT: act = ap->x.stp->index; break; - case REDUCE: act = ap->x.rp->index + lemp->nstate; break; - case ERROR: act = lemp->nstate + lemp->nrule; break; - case ACCEPT: act = lemp->nstate + lemp->nrule + 1; break; - default: act = -1; break; - } - return act; -} - -#define LINESIZE 1000 -/* The next cluster of routines are for reading the template file -** and writing the results to the generated parser */ -/* The first function transfers data from "in" to "out" until -** a line is seen which begins with "%%". The line number is -** tracked. -** -** if name!=0, then any word that begin with "Parse" is changed to -** begin with *name instead. -*/ -PRIVATE void tplt_xfer(name,in,out,lineno) -char *name; -FILE *in; -FILE *out; -int *lineno; -{ - int i, iStart; - char line[LINESIZE]; - while( fgets(line,LINESIZE,in) && (line[0]!='%' || line[1]!='%') ){ - (*lineno)++; - iStart = 0; - if( name ){ - for(i=0; line[i]; i++){ - if( line[i]=='P' && strncmp(&line[i],"Parse",5)==0 - && (i==0 || !isalpha(line[i-1])) - ){ - if( i>iStart ) fprintf(out,"%.*s",i-iStart,&line[iStart]); - fprintf(out,"%s",name); - i += 4; - iStart = i+1; - } - } - } - fprintf(out,"%s",&line[iStart]); - } -} - -/* The next function finds the template file and opens it, returning -** a pointer to the opened file. */ -PRIVATE FILE *tplt_open(lemp) -struct lemon *lemp; -{ - static char templatename[] = "lempar.c"; - char buf[1000]; - FILE *in; - char *tpltname; - char *cp; - - cp = strrchr(lemp->filename,'.'); - if( cp ){ - sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); - }else{ - sprintf(buf,"%s.lt",lemp->filename); - } - if( access(buf,004)==0 ){ - tpltname = buf; - }else if( access(templatename,004)==0 ){ - tpltname = templatename; - }else{ - tpltname = pathsearch(lemp->argv0,templatename,0); - } - if( tpltname==0 ){ - fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", - templatename); - lemp->errorcnt++; - return 0; - } - in = fopen(tpltname,"rb"); - if( in==0 ){ - fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); - lemp->errorcnt++; - return 0; - } - return in; -} - -/* Print a #line directive line to the output file. */ -PRIVATE void tplt_linedir(out,lineno,filename) -FILE *out; -int lineno; -char *filename; -{ - fprintf(out,"#line %d \"",lineno); - while( *filename ){ - if( *filename == '\\' ) putc('\\',out); - putc(*filename,out); - filename++; - } - fprintf(out,"\"\n"); -} - -/* Print a string to the file and keep the linenumber up to date */ -PRIVATE void tplt_print(out,lemp,str,strln,lineno) -FILE *out; -struct lemon *lemp; -char *str; -int strln; -int *lineno; -{ - if( str==0 ) return; - tplt_linedir(out,strln,lemp->filename); - (*lineno)++; - while( *str ){ - if( *str=='\n' ) (*lineno)++; - putc(*str,out); - str++; - } - if( str[-1]!='\n' ){ - putc('\n',out); - (*lineno)++; - } - tplt_linedir(out,*lineno+2,lemp->outname); - (*lineno)+=2; - return; -} - -/* -** The following routine emits code for the destructor for the -** symbol sp -*/ -void emit_destructor_code(out,sp,lemp,lineno) -FILE *out; -struct symbol *sp; -struct lemon *lemp; -int *lineno; -{ - char *cp = 0; - - int linecnt = 0; - if( sp->type==TERMINAL ){ - cp = lemp->tokendest; - if( cp==0 ) return; - tplt_linedir(out,lemp->tokendestln,lemp->filename); - fprintf(out,"{"); - }else if( sp->destructor ){ - cp = sp->destructor; - tplt_linedir(out,sp->destructorln,lemp->filename); - fprintf(out,"{"); - }else if( lemp->vardest ){ - cp = lemp->vardest; - if( cp==0 ) return; - tplt_linedir(out,lemp->vardestln,lemp->filename); - fprintf(out,"{"); - }else{ - assert( 0 ); /* Cannot happen */ - } - for(; *cp; cp++){ - if( *cp=='$' && cp[1]=='$' ){ - fprintf(out,"(yypminor->yy%d)",sp->dtnum); - cp++; - continue; - } - if( *cp=='\n' ) linecnt++; - fputc(*cp,out); - } - (*lineno) += 3 + linecnt; - fprintf(out,"}\n"); - tplt_linedir(out,*lineno,lemp->outname); - return; -} - -/* -** Return TRUE (non-zero) if the given symbol has a destructor. -*/ -int has_destructor(sp, lemp) -struct symbol *sp; -struct lemon *lemp; -{ - int ret; - if( sp->type==TERMINAL ){ - ret = lemp->tokendest!=0; - }else{ - ret = lemp->vardest!=0 || sp->destructor!=0; - } - return ret; -} - -/* -** Append text to a dynamically allocated string. If zText is 0 then -** reset the string to be empty again. Always return the complete text -** of the string (which is overwritten with each call). -** -** n bytes of zText are stored. If n==0 then all of zText up to the first -** \000 terminator is stored. zText can contain up to two instances of -** %d. The values of p1 and p2 are written into the first and second -** %d. -** -** If n==-1, then the previous character is overwritten. -*/ -PRIVATE char *append_str(char *zText, int n, int p1, int p2){ - static char *z = 0; - static int alloced = 0; - static int used = 0; - int c; - char zInt[40]; - - if( zText==0 ){ - used = 0; - return z; - } - if( n<=0 ){ - if( n<0 ){ - used += n; - assert( used>=0 ); - } - n = strlen(zText); - } - if( n+sizeof(zInt)*2+used >= alloced ){ - alloced = n + sizeof(zInt)*2 + used + 200; - z = realloc(z, alloced); - } - if( z==0 ) return ""; - while( n-- > 0 ){ - c = *(zText++); - if( c=='%' && zText[0]=='d' ){ - sprintf(zInt, "%d", p1); - p1 = p2; - strcpy(&z[used], zInt); - used += strlen(&z[used]); - zText++; - n--; - }else{ - z[used++] = c; - } - } - z[used] = 0; - return z; -} - -/* -** zCode is a string that is the action associated with a rule. Expand -** the symbols in this string so that the refer to elements of the parser -** stack. -*/ -PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){ - char *cp, *xp; - int i; - char lhsused = 0; /* True if the LHS element has been used */ - char used[MAXRHS]; /* True for each RHS element which is used */ - - for(i=0; inrhs; i++) used[i] = 0; - lhsused = 0; - - append_str(0,0,0,0); - for(cp=rp->code; *cp; cp++){ - if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){ - char saved; - for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++); - saved = *xp; - *xp = 0; - if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){ - append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0); - cp = xp; - lhsused = 1; - }else{ - for(i=0; inrhs; i++){ - if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){ - if( cp!=rp->code && cp[-1]=='@' ){ - /* If the argument is of the form @X then substituted - ** the token number of X, not the value of X */ - append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0); - }else{ - append_str("yymsp[%d].minor.yy%d",0, - i-rp->nrhs+1,rp->rhs[i]->dtnum); - } - cp = xp; - used[i] = 1; - break; - } - } - } - *xp = saved; - } - append_str(cp, 1, 0, 0); - } /* End loop */ - - /* Check to make sure the LHS has been used */ - if( rp->lhsalias && !lhsused ){ - ErrorMsg(lemp->filename,rp->ruleline, - "Label \"%s\" for \"%s(%s)\" is never used.", - rp->lhsalias,rp->lhs->name,rp->lhsalias); - lemp->errorcnt++; - } - - /* Generate destructor code for RHS symbols which are not used in the - ** reduce code */ - for(i=0; inrhs; i++){ - if( rp->rhsalias[i] && !used[i] ){ - ErrorMsg(lemp->filename,rp->ruleline, - "Label %s for \"%s(%s)\" is never used.", - rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]); - lemp->errorcnt++; - }else if( rp->rhsalias[i]==0 ){ - if( has_destructor(rp->rhs[i],lemp) ){ - append_str(" yy_destructor(%d,&yymsp[%d].minor);\n", 0, - rp->rhs[i]->index,i-rp->nrhs+1); - }else{ - /* No destructor defined for this term */ - } - } - } - cp = append_str(0,0,0,0); - rp->code = Strsafe(cp); -} - -/* -** Generate code which executes when the rule "rp" is reduced. Write -** the code to "out". Make sure lineno stays up-to-date. -*/ -PRIVATE void emit_code(out,rp,lemp,lineno) -FILE *out; -struct rule *rp; -struct lemon *lemp; -int *lineno; -{ - char *cp; - int linecnt = 0; - - /* Generate code to do the reduce action */ - if( rp->code ){ - tplt_linedir(out,rp->line,lemp->filename); - fprintf(out,"{%s",rp->code); - for(cp=rp->code; *cp; cp++){ - if( *cp=='\n' ) linecnt++; - } /* End loop */ - (*lineno) += 3 + linecnt; - fprintf(out,"}\n"); - tplt_linedir(out,*lineno,lemp->outname); - } /* End if( rp->code ) */ - - return; -} - -/* -** Print the definition of the union used for the parser's data stack. -** This union contains fields for every possible data type for tokens -** and nonterminals. In the process of computing and printing this -** union, also set the ".dtnum" field of every terminal and nonterminal -** symbol. -*/ -void print_stack_union(out,lemp,plineno,mhflag) -FILE *out; /* The output stream */ -struct lemon *lemp; /* The main info structure for this parser */ -int *plineno; /* Pointer to the line number */ -int mhflag; /* True if generating makeheaders output */ -{ - int lineno = *plineno; /* The line number of the output */ - char **types; /* A hash table of datatypes */ - int arraysize; /* Size of the "types" array */ - int maxdtlength; /* Maximum length of any ".datatype" field. */ - char *stddt; /* Standardized name for a datatype */ - int i,j; /* Loop counters */ - int hash; /* For hashing the name of a type */ - char *name; /* Name of the parser */ - - /* Allocate and initialize types[] and allocate stddt[] */ - arraysize = lemp->nsymbol * 2; - types = (char**)malloc( arraysize * sizeof(char*) ); - for(i=0; ivartype ){ - maxdtlength = strlen(lemp->vartype); - } - for(i=0; insymbol; i++){ - int len; - struct symbol *sp = lemp->symbols[i]; - if( sp->datatype==0 ) continue; - len = strlen(sp->datatype); - if( len>maxdtlength ) maxdtlength = len; - } - stddt = (char*)malloc( maxdtlength*2 + 1 ); - if( types==0 || stddt==0 ){ - fprintf(stderr,"Out of memory.\n"); - exit(1); - } - - /* Build a hash table of datatypes. The ".dtnum" field of each symbol - ** is filled in with the hash index plus 1. A ".dtnum" value of 0 is - ** used for terminal symbols. If there is no %default_type defined then - ** 0 is also used as the .dtnum value for nonterminals which do not specify - ** a datatype using the %type directive. - */ - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - char *cp; - if( sp==lemp->errsym ){ - sp->dtnum = arraysize+1; - continue; - } - if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){ - sp->dtnum = 0; - continue; - } - cp = sp->datatype; - if( cp==0 ) cp = lemp->vartype; - j = 0; - while( isspace(*cp) ) cp++; - while( *cp ) stddt[j++] = *cp++; - while( j>0 && isspace(stddt[j-1]) ) j--; - stddt[j] = 0; - hash = 0; - for(j=0; stddt[j]; j++){ - hash = hash*53 + stddt[j]; - } - hash = (hash & 0x7fffffff)%arraysize; - while( types[hash] ){ - if( strcmp(types[hash],stddt)==0 ){ - sp->dtnum = hash + 1; - break; - } - hash++; - if( hash>=arraysize ) hash = 0; - } - if( types[hash]==0 ){ - sp->dtnum = hash + 1; - types[hash] = (char*)malloc( strlen(stddt)+1 ); - if( types[hash]==0 ){ - fprintf(stderr,"Out of memory.\n"); - exit(1); - } - strcpy(types[hash],stddt); - } - } - - /* Print out the definition of YYTOKENTYPE and YYMINORTYPE */ - name = lemp->name ? lemp->name : "Parse"; - lineno = *plineno; - if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; } - fprintf(out,"#define %sTOKENTYPE %s\n",name, - lemp->tokentype?lemp->tokentype:"void*"); lineno++; - if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } - fprintf(out,"typedef union {\n"); lineno++; - fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++; - for(i=0; ierrsym->dtnum); lineno++; - free(stddt); - free(types); - fprintf(out,"} YYMINORTYPE;\n"); lineno++; - *plineno = lineno; -} - -/* -** Return the name of a C datatype able to represent values between -** lwr and upr, inclusive. -*/ -static const char *minimum_size_type(int lwr, int upr){ - if( lwr>=0 ){ - if( upr<=255 ){ - return "unsigned char"; - }else if( upr<65535 ){ - return "unsigned short int"; - }else{ - return "unsigned int"; - } - }else if( lwr>=-127 && upr<=127 ){ - return "signed char"; - }else if( lwr>=-32767 && upr<32767 ){ - return "short"; - }else{ - return "int"; - } -} - -/* -** Each state contains a set of token transaction and a set of -** nonterminal transactions. Each of these sets makes an instance -** of the following structure. An array of these structures is used -** to order the creation of entries in the yy_action[] table. -*/ -struct axset { - struct state *stp; /* A pointer to a state */ - int isTkn; /* True to use tokens. False for non-terminals */ - int nAction; /* Number of actions */ -}; - -/* -** Compare to axset structures for sorting purposes -*/ -static int axset_compare(const void *a, const void *b){ - struct axset *p1 = (struct axset*)a; - struct axset *p2 = (struct axset*)b; - return p2->nAction - p1->nAction; -} - -/* Generate C source code for the parser */ -void ReportTable(lemp, mhflag) -struct lemon *lemp; -int mhflag; /* Output in makeheaders format if true */ -{ - FILE *out, *in; - char line[LINESIZE]; - int lineno; - struct state *stp; - struct action *ap; - struct rule *rp; - struct acttab *pActtab; - int i, j, n; - char *name; - int mnTknOfst, mxTknOfst; - int mnNtOfst, mxNtOfst; - struct axset *ax; - - in = tplt_open(lemp); - if( in==0 ) return; - out = file_open(lemp,".c","wb"); - if( out==0 ){ - fclose(in); - return; - } - lineno = 1; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the include code, if any */ - tplt_print(out,lemp,lemp->include,lemp->includeln,&lineno); - if( mhflag ){ - char *name = file_makename(lemp, ".h"); - fprintf(out,"#include \"%s\"\n", name); lineno++; - free(name); - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate #defines for all tokens */ - if( mhflag ){ - char *prefix; - fprintf(out,"#if INTERFACE\n"); lineno++; - if( lemp->tokenprefix ) prefix = lemp->tokenprefix; - else prefix = ""; - for(i=1; interminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - lineno++; - } - fprintf(out,"#endif\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the defines */ - fprintf(out,"#define YYCODETYPE %s\n", - minimum_size_type(0, lemp->nsymbol+5)); lineno++; - fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++; - fprintf(out,"#define YYACTIONTYPE %s\n", - minimum_size_type(0, lemp->nstate+lemp->nrule+5)); lineno++; - print_stack_union(out,lemp,&lineno,mhflag); - if( lemp->stacksize ){ - if( atoi(lemp->stacksize)<=0 ){ - ErrorMsg(lemp->filename,0, -"Illegal stack size: [%s]. The stack size should be an integer constant.", - lemp->stacksize); - lemp->errorcnt++; - lemp->stacksize = "100"; - } - fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize); lineno++; - }else{ - fprintf(out,"#define YYSTACKDEPTH 100\n"); lineno++; - } - if( mhflag ){ - fprintf(out,"#if INTERFACE\n"); lineno++; - } - name = lemp->name ? lemp->name : "Parse"; - if( lemp->arg && lemp->arg[0] ){ - int i; - i = strlen(lemp->arg); - while( i>=1 && isspace(lemp->arg[i-1]) ) i--; - while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; - fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n", - name,lemp->arg,&lemp->arg[i]); lineno++; - fprintf(out,"#define %sARG_STORE yypParser->%s = %s\n", - name,&lemp->arg[i],&lemp->arg[i]); lineno++; - }else{ - fprintf(out,"#define %sARG_SDECL\n",name); lineno++; - fprintf(out,"#define %sARG_PDECL\n",name); lineno++; - fprintf(out,"#define %sARG_FETCH\n",name); lineno++; - fprintf(out,"#define %sARG_STORE\n",name); lineno++; - } - if( mhflag ){ - fprintf(out,"#endif\n"); lineno++; - } - fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++; - fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; - fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; - fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; - if( lemp->has_fallback ){ - fprintf(out,"#define YYFALLBACK 1\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the action table and its associates: - ** - ** 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. - */ - - /* Compute the actions on all states and count them up */ - ax = malloc( sizeof(ax[0])*lemp->nstate*2 ); - if( ax==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - stp->nTknAct = stp->nNtAct = 0; - stp->iDflt = lemp->nstate + lemp->nrule; - stp->iTknOfst = NO_OFFSET; - stp->iNtOfst = NO_OFFSET; - for(ap=stp->ap; ap; ap=ap->next){ - if( compute_action(lemp,ap)>=0 ){ - if( ap->sp->indexnterminal ){ - stp->nTknAct++; - }else if( ap->sp->indexnsymbol ){ - stp->nNtAct++; - }else{ - stp->iDflt = compute_action(lemp, ap); - } - } - } - ax[i*2].stp = stp; - ax[i*2].isTkn = 1; - ax[i*2].nAction = stp->nTknAct; - ax[i*2+1].stp = stp; - ax[i*2+1].isTkn = 0; - ax[i*2+1].nAction = stp->nNtAct; - } - mxTknOfst = mnTknOfst = 0; - mxNtOfst = mnNtOfst = 0; - - /* Compute the action table. In order to try to keep the size of the - ** action table to a minimum, the heuristic of placing the largest action - ** sets first is used. - */ - qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare); - pActtab = acttab_alloc(); - for(i=0; instate*2 && ax[i].nAction>0; i++){ - stp = ax[i].stp; - if( ax[i].isTkn ){ - for(ap=stp->ap; ap; ap=ap->next){ - int action; - if( ap->sp->index>=lemp->nterminal ) continue; - action = compute_action(lemp, ap); - if( action<0 ) continue; - acttab_action(pActtab, ap->sp->index, action); - } - stp->iTknOfst = acttab_insert(pActtab); - if( stp->iTknOfstiTknOfst; - if( stp->iTknOfst>mxTknOfst ) mxTknOfst = stp->iTknOfst; - }else{ - for(ap=stp->ap; ap; ap=ap->next){ - int action; - if( ap->sp->indexnterminal ) continue; - if( ap->sp->index==lemp->nsymbol ) continue; - action = compute_action(lemp, ap); - if( action<0 ) continue; - acttab_action(pActtab, ap->sp->index, action); - } - stp->iNtOfst = acttab_insert(pActtab); - if( stp->iNtOfstiNtOfst; - if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst; - } - } - free(ax); - - /* Output the yy_action table */ - fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++; - n = acttab_size(pActtab); - for(i=j=0; insymbol + lemp->nrule + 2; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", action); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_lookahead table */ - fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++; - for(i=j=0; insymbol; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", la); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_shift_ofst[] table */ - fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++; - fprintf(out, "static const %s yy_shift_ofst[] = {\n", - minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++; - n = lemp->nstate; - for(i=j=0; isorted[i]; - ofst = stp->iTknOfst; - if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", ofst); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_reduce_ofst[] table */ - fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++; - fprintf(out, "static const %s yy_reduce_ofst[] = {\n", - minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++; - n = lemp->nstate; - for(i=j=0; isorted[i]; - ofst = stp->iNtOfst; - if( ofst==NO_OFFSET ) ofst = mnNtOfst - 1; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", ofst); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the default action table */ - fprintf(out, "static const YYACTIONTYPE yy_default[] = {\n"); lineno++; - n = lemp->nstate; - for(i=j=0; isorted[i]; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", stp->iDflt); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the table of fallback tokens. - */ - if( lemp->has_fallback ){ - for(i=0; interminal; i++){ - struct symbol *p = lemp->symbols[i]; - if( p->fallback==0 ){ - fprintf(out, " 0, /* %10s => nothing */\n", p->name); - }else{ - fprintf(out, " %3d, /* %10s => %s */\n", p->fallback->index, - p->name, p->fallback->name); - } - lineno++; - } - } - tplt_xfer(lemp->name, in, out, &lineno); - - /* Generate a table containing the symbolic name of every symbol - */ - for(i=0; insymbol; i++){ - sprintf(line,"\"%s\",",lemp->symbols[i]->name); - fprintf(out," %-15s",line); - if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } - } - if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate a table containing a text string that describes every - ** rule in the rule set of the grammer. This information is used - ** when tracing REDUCE actions. - */ - for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ - assert( rp->index==i ); - fprintf(out," /* %3d */ \"%s ::=", i, rp->lhs->name); - for(j=0; jnrhs; j++) fprintf(out," %s",rp->rhs[j]->name); - fprintf(out,"\",\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes every time a symbol is popped from - ** the stack while processing errors or while destroying the parser. - ** (In other words, generate the %destructor actions) - */ - if( lemp->tokendest ){ - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type!=TERMINAL ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; - } - for(i=0; insymbol && lemp->symbols[i]->type!=TERMINAL; i++); - if( insymbol ){ - emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - } - if( lemp->vardest ){ - struct symbol *dflt_sp = 0; - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || - sp->index<=0 || sp->destructor!=0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; - dflt_sp = sp; - } - if( dflt_sp!=0 ){ - emit_destructor_code(out,dflt_sp,lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - } - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; - - /* Combine duplicate destructors into a single case */ - for(j=i+1; jnsymbol; j++){ - struct symbol *sp2 = lemp->symbols[j]; - if( sp2 && sp2->type!=TERMINAL && sp2->destructor - && sp2->dtnum==sp->dtnum - && strcmp(sp->destructor,sp2->destructor)==0 ){ - fprintf(out," case %d:\n",sp2->index); lineno++; - sp2->destructor = 0; - } - } - - emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes whenever the parser stack overflows */ - tplt_print(out,lemp,lemp->overflow,lemp->overflowln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the table of rule information - ** - ** Note: This code depends on the fact that rules are number - ** sequentually beginning with 0. - */ - for(rp=lemp->rule; rp; rp=rp->next){ - fprintf(out," { %d, %d },\n",rp->lhs->index,rp->nrhs); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which execution during each REDUCE action */ - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->code ) translate_code(lemp, rp); - } - for(rp=lemp->rule; rp; rp=rp->next){ - struct rule *rp2; - if( rp->code==0 ) continue; - fprintf(out," case %d:\n",rp->index); lineno++; - for(rp2=rp->next; rp2; rp2=rp2->next){ - if( rp2->code==rp->code ){ - fprintf(out," case %d:\n",rp2->index); lineno++; - rp2->code = 0; - } - } - emit_code(out,rp,lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes if a parse fails */ - tplt_print(out,lemp,lemp->failure,lemp->failureln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes when a syntax error occurs */ - tplt_print(out,lemp,lemp->error,lemp->errorln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes when the parser accepts its input */ - tplt_print(out,lemp,lemp->accept,lemp->acceptln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Append any addition code the user desires */ - tplt_print(out,lemp,lemp->extracode,lemp->extracodeln,&lineno); - - fclose(in); - fclose(out); - return; -} - -/* Generate a header file for the parser */ -void ReportHeader(lemp) -struct lemon *lemp; -{ - FILE *out, *in; - char *prefix; - char line[LINESIZE]; - char pattern[LINESIZE]; - int i; - - if( lemp->tokenprefix ) prefix = lemp->tokenprefix; - else prefix = ""; - in = file_open(lemp,".h","rb"); - if( in ){ - for(i=1; interminal && fgets(line,LINESIZE,in); i++){ - sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - if( strcmp(line,pattern) ) break; - } - fclose(in); - if( i==lemp->nterminal ){ - /* No change in the file. Don't rewrite it. */ - return; - } - } - out = file_open(lemp,".h","wb"); - if( out ){ - for(i=1; interminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - } - fclose(out); - } - return; -} - -/* Reduce the size of the action tables, if possible, by making use -** of defaults. -** -** In this version, we take the most frequent REDUCE action and make -** it the default. Only default a reduce if there are more than one. -*/ -void CompressTables(lemp) -struct lemon *lemp; -{ - struct state *stp; - struct action *ap, *ap2; - struct rule *rp, *rp2, *rbest; - int nbest, n; - int i; - - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - nbest = 0; - rbest = 0; - - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->type!=REDUCE ) continue; - rp = ap->x.rp; - if( rp==rbest ) continue; - n = 1; - for(ap2=ap->next; ap2; ap2=ap2->next){ - if( ap2->type!=REDUCE ) continue; - rp2 = ap2->x.rp; - if( rp2==rbest ) continue; - if( rp2==rp ) n++; - } - if( n>nbest ){ - nbest = n; - rbest = rp; - } - } - - /* Do not make a default if the number of rules to default - ** is not at least 2 */ - if( nbest<2 ) continue; - - - /* Combine matching REDUCE actions into a single default */ - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->type==REDUCE && ap->x.rp==rbest ) break; - } - assert( ap ); - ap->sp = Symbol_new("{default}"); - for(ap=ap->next; ap; ap=ap->next){ - if( ap->type==REDUCE && ap->x.rp==rbest ) ap->type = NOT_USED; - } - stp->ap = Action_sort(stp->ap); - } -} - -/***************** From the file "set.c" ************************************/ -/* -** Set manipulation routines for the LEMON parser generator. -*/ - -static int size = 0; - -/* Set the set size */ -void SetSize(n) -int n; -{ - size = n+1; -} - -/* Allocate a new set */ -char *SetNew(){ - char *s; - int i; - s = (char*)malloc( size ); - if( s==0 ){ - extern void memory_error(); - memory_error(); - } - for(i=0; isize = 1024; - x1a->count = 0; - x1a->tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*1024 ); - if( x1a->tbl==0 ){ - free(x1a); - x1a = 0; - }else{ - int i; - x1a->ht = (x1node**)&(x1a->tbl[1024]); - for(i=0; i<1024; i++) x1a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Strsafe_insert(data) -char *data; -{ - x1node *np; - int h; - int ph; - - if( x1a==0 ) return 0; - ph = strhash(data); - h = ph & (x1a->size-1); - np = x1a->ht[h]; - while( np ){ - if( strcmp(np->data,data)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x1a->count>=x1a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x1 array; - array.size = size = x1a->size*2; - array.count = x1a->count; - array.tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x1node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x1node *oldnp, *newnp; - oldnp = &(x1a->tbl[i]); - h = strhash(oldnp->data) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x1a->tbl); - *x1a = array; - } - /* Insert the new data */ - h = ph & (x1a->size-1); - np = &(x1a->tbl[x1a->count++]); - np->data = data; - if( x1a->ht[h] ) x1a->ht[h]->from = &(np->next); - np->next = x1a->ht[h]; - x1a->ht[h] = np; - np->from = &(x1a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -char *Strsafe_find(key) -char *key; -{ - int h; - x1node *np; - - if( x1a==0 ) return 0; - h = strhash(key) & (x1a->size-1); - np = x1a->ht[h]; - while( np ){ - if( strcmp(np->data,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return a pointer to the (terminal or nonterminal) symbol "x". -** Create a new symbol if this is the first time "x" has been seen. -*/ -struct symbol *Symbol_new(x) -char *x; -{ - struct symbol *sp; - - sp = Symbol_find(x); - if( sp==0 ){ - sp = (struct symbol *)malloc( sizeof(struct symbol) ); - MemoryCheck(sp); - sp->name = Strsafe(x); - sp->type = isupper(*x) ? TERMINAL : NONTERMINAL; - sp->rule = 0; - sp->fallback = 0; - sp->prec = -1; - sp->assoc = UNK; - sp->firstset = 0; - sp->lambda = B_FALSE; - sp->destructor = 0; - sp->datatype = 0; - Symbol_insert(sp,sp->name); - } - return sp; -} - -/* Compare two symbols for working purposes -** -** Symbols that begin with upper case letters (terminals or tokens) -** must sort before symbols that begin with lower case letters -** (non-terminals). Other than that, the order does not matter. -** -** We find experimentally that leaving the symbols in their original -** order (the order they appeared in the grammar file) gives the -** smallest parser tables in SQLite. -*/ -int Symbolcmpp(struct symbol **a, struct symbol **b){ - int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); - int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); - return i1-i2; -} - -/* There is one instance of the following structure for each -** associative array of type "x2". -*/ -struct s_x2 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x2node *tbl; /* The data stored here */ - struct s_x2node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x2". -*/ -typedef struct s_x2node { - struct symbol *data; /* The data */ - char *key; /* The key */ - struct s_x2node *next; /* Next entry with the same hash */ - struct s_x2node **from; /* Previous link */ -} x2node; - -/* There is only one instance of the array, which is the following */ -static struct s_x2 *x2a; - -/* Allocate a new associative array */ -void Symbol_init(){ - if( x2a ) return; - x2a = (struct s_x2*)malloc( sizeof(struct s_x2) ); - if( x2a ){ - x2a->size = 128; - x2a->count = 0; - x2a->tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*128 ); - if( x2a->tbl==0 ){ - free(x2a); - x2a = 0; - }else{ - int i; - x2a->ht = (x2node**)&(x2a->tbl[128]); - for(i=0; i<128; i++) x2a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Symbol_insert(data,key) -struct symbol *data; -char *key; -{ - x2node *np; - int h; - int ph; - - if( x2a==0 ) return 0; - ph = strhash(key); - h = ph & (x2a->size-1); - np = x2a->ht[h]; - while( np ){ - if( strcmp(np->key,key)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x2a->count>=x2a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x2 array; - array.size = size = x2a->size*2; - array.count = x2a->count; - array.tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x2node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x2node *oldnp, *newnp; - oldnp = &(x2a->tbl[i]); - h = strhash(oldnp->key) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->key = oldnp->key; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x2a->tbl); - *x2a = array; - } - /* Insert the new data */ - h = ph & (x2a->size-1); - np = &(x2a->tbl[x2a->count++]); - np->key = key; - np->data = data; - if( x2a->ht[h] ) x2a->ht[h]->from = &(np->next); - np->next = x2a->ht[h]; - x2a->ht[h] = np; - np->from = &(x2a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct symbol *Symbol_find(key) -char *key; -{ - int h; - x2node *np; - - if( x2a==0 ) return 0; - h = strhash(key) & (x2a->size-1); - np = x2a->ht[h]; - while( np ){ - if( strcmp(np->key,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return the n-th data. Return NULL if n is out of range. */ -struct symbol *Symbol_Nth(n) -int n; -{ - struct symbol *data; - if( x2a && n>0 && n<=x2a->count ){ - data = x2a->tbl[n-1].data; - }else{ - data = 0; - } - return data; -} - -/* Return the size of the array */ -int Symbol_count() -{ - return x2a ? x2a->count : 0; -} - -/* Return an array of pointers to all data in the table. -** The array is obtained from malloc. Return NULL if memory allocation -** problems, or if the array is empty. */ -struct symbol **Symbol_arrayof() -{ - struct symbol **array; - int i,size; - if( x2a==0 ) return 0; - size = x2a->count; - array = (struct symbol **)malloc( sizeof(struct symbol *)*size ); - if( array ){ - for(i=0; itbl[i].data; - } - return array; -} - -/* Compare two configurations */ -int Configcmp(a,b) -struct config *a; -struct config *b; -{ - int x; - x = a->rp->index - b->rp->index; - if( x==0 ) x = a->dot - b->dot; - return x; -} - -/* Compare two states */ -PRIVATE int statecmp(a,b) -struct config *a; -struct config *b; -{ - int rc; - for(rc=0; rc==0 && a && b; a=a->bp, b=b->bp){ - rc = a->rp->index - b->rp->index; - if( rc==0 ) rc = a->dot - b->dot; - } - if( rc==0 ){ - if( a ) rc = 1; - if( b ) rc = -1; - } - return rc; -} - -/* Hash a state */ -PRIVATE int statehash(a) -struct config *a; -{ - int h=0; - while( a ){ - h = h*571 + a->rp->index*37 + a->dot; - a = a->bp; - } - return h; -} - -/* Allocate a new state structure */ -struct state *State_new() -{ - struct state *new; - new = (struct state *)malloc( sizeof(struct state) ); - MemoryCheck(new); - return new; -} - -/* There is one instance of the following structure for each -** associative array of type "x3". -*/ -struct s_x3 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x3node *tbl; /* The data stored here */ - struct s_x3node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x3". -*/ -typedef struct s_x3node { - struct state *data; /* The data */ - struct config *key; /* The key */ - struct s_x3node *next; /* Next entry with the same hash */ - struct s_x3node **from; /* Previous link */ -} x3node; - -/* There is only one instance of the array, which is the following */ -static struct s_x3 *x3a; - -/* Allocate a new associative array */ -void State_init(){ - if( x3a ) return; - x3a = (struct s_x3*)malloc( sizeof(struct s_x3) ); - if( x3a ){ - x3a->size = 128; - x3a->count = 0; - x3a->tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*128 ); - if( x3a->tbl==0 ){ - free(x3a); - x3a = 0; - }else{ - int i; - x3a->ht = (x3node**)&(x3a->tbl[128]); - for(i=0; i<128; i++) x3a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int State_insert(data,key) -struct state *data; -struct config *key; -{ - x3node *np; - int h; - int ph; - - if( x3a==0 ) return 0; - ph = statehash(key); - h = ph & (x3a->size-1); - np = x3a->ht[h]; - while( np ){ - if( statecmp(np->key,key)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x3a->count>=x3a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x3 array; - array.size = size = x3a->size*2; - array.count = x3a->count; - array.tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x3node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x3node *oldnp, *newnp; - oldnp = &(x3a->tbl[i]); - h = statehash(oldnp->key) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->key = oldnp->key; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x3a->tbl); - *x3a = array; - } - /* Insert the new data */ - h = ph & (x3a->size-1); - np = &(x3a->tbl[x3a->count++]); - np->key = key; - np->data = data; - if( x3a->ht[h] ) x3a->ht[h]->from = &(np->next); - np->next = x3a->ht[h]; - x3a->ht[h] = np; - np->from = &(x3a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct state *State_find(key) -struct config *key; -{ - int h; - x3node *np; - - if( x3a==0 ) return 0; - h = statehash(key) & (x3a->size-1); - np = x3a->ht[h]; - while( np ){ - if( statecmp(np->key,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return an array of pointers to all data in the table. -** The array is obtained from malloc. Return NULL if memory allocation -** problems, or if the array is empty. */ -struct state **State_arrayof() -{ - struct state **array; - int i,size; - if( x3a==0 ) return 0; - size = x3a->count; - array = (struct state **)malloc( sizeof(struct state *)*size ); - if( array ){ - for(i=0; itbl[i].data; - } - return array; -} - -/* Hash a configuration */ -PRIVATE int confighash(a) -struct config *a; -{ - int h=0; - h = h*571 + a->rp->index*37 + a->dot; - return h; -} - -/* There is one instance of the following structure for each -** associative array of type "x4". -*/ -struct s_x4 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x4node *tbl; /* The data stored here */ - struct s_x4node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x4". -*/ -typedef struct s_x4node { - struct config *data; /* The data */ - struct s_x4node *next; /* Next entry with the same hash */ - struct s_x4node **from; /* Previous link */ -} x4node; - -/* There is only one instance of the array, which is the following */ -static struct s_x4 *x4a; - -/* Allocate a new associative array */ -void Configtable_init(){ - if( x4a ) return; - x4a = (struct s_x4*)malloc( sizeof(struct s_x4) ); - if( x4a ){ - x4a->size = 64; - x4a->count = 0; - x4a->tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*64 ); - if( x4a->tbl==0 ){ - free(x4a); - x4a = 0; - }else{ - int i; - x4a->ht = (x4node**)&(x4a->tbl[64]); - for(i=0; i<64; i++) x4a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Configtable_insert(data) -struct config *data; -{ - x4node *np; - int h; - int ph; - - if( x4a==0 ) return 0; - ph = confighash(data); - h = ph & (x4a->size-1); - np = x4a->ht[h]; - while( np ){ - if( Configcmp(np->data,data)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x4a->count>=x4a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x4 array; - array.size = size = x4a->size*2; - array.count = x4a->count; - array.tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x4node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x4node *oldnp, *newnp; - oldnp = &(x4a->tbl[i]); - h = confighash(oldnp->data) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x4a->tbl); - *x4a = array; - } - /* Insert the new data */ - h = ph & (x4a->size-1); - np = &(x4a->tbl[x4a->count++]); - np->data = data; - if( x4a->ht[h] ) x4a->ht[h]->from = &(np->next); - np->next = x4a->ht[h]; - x4a->ht[h] = np; - np->from = &(x4a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct config *Configtable_find(key) -struct config *key; -{ - int h; - x4node *np; - - if( x4a==0 ) return 0; - h = confighash(key) & (x4a->size-1); - np = x4a->ht[h]; - while( np ){ - if( Configcmp(np->data,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Remove all data from the table. Pass each data to the function "f" -** as it is removed. ("f" may be null to avoid this step.) */ -void Configtable_clear(f) -int(*f)(/* struct config * */); -{ - int i; - if( x4a==0 || x4a->count==0 ) return; - if( f ) for(i=0; icount; i++) (*f)(x4a->tbl[i].data); - for(i=0; isize; i++) x4a->ht[i] = 0; - x4a->count = 0; - return; -} diff --git a/sqlite/tool/lempar.c b/sqlite/tool/lempar.c deleted file mode 100644 index 685f952..0000000 --- a/sqlite/tool/lempar.c +++ /dev/null @@ -1,714 +0,0 @@ -/* 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 -%% -/* 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. -** ParseTOKENTYPE 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 ParseTOKENTYPE. The entry in the union -** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. -** ParseARG_SDECL A static variable declaration for the %extra_argument -** ParseARG_PDECL A parameter declaration for the %extra_argument -** ParseARG_STORE Code to store %extra_argument into yypParser -** ParseARG_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 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. -*/ -%% -#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[] = { -%% -}; -#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 */ - ParseARG_SDECL /* A place to hold %extra_argument */ - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -#include -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: -**
    -**
  • A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -**
  • A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -**
-** -** Outputs: -** None. -*/ -void ParseTrace(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[] = { -%% -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { -%% -}; -#endif /* NDEBUG */ - -/* -** This function returns the symbolic name associated with a token -** value. -*/ -const char *ParseTokenName(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 Parse and ParseFree. -*/ -void *ParseAlloc(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. - */ -%% - 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: -**
    -**
  • A pointer to the parser. This should be a pointer -** obtained from ParseAlloc. -**
  • A pointer to a function used to reclaim memory obtained -** from malloc. -**
-*/ -void ParseFree( - 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 %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 ){ - ParseARG_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 */ -%% - ParseARG_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[] = { -%% -}; - -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 */ - ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno - ** { ... } // User supplied code - ** #line - ** 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 */ -){ - ParseARG_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 */ -%% - ParseARG_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 */ -){ - ParseARG_FETCH; -#define TOKEN (yyminor.yy0) -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - ParseARG_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 */ -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "ParseAlloc" 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: -**
    -**
  • A pointer to the parser (an opaque structure.) -**
  • The major token number. -**
  • The minor token number. -**
  • An option argument of a grammar-specified type. -**
-** -** Outputs: -** None. -*/ -void Parse( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - ParseTOKENTYPE yyminor /* The value for the token */ - ParseARG_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; - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; - yyendofinput = (yymajor==0); - ParseARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,yymajor); - if( yyactyyerrcnt--; - 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/sqlite/tool/memleak.awk b/sqlite/tool/memleak.awk deleted file mode 100644 index 928d3b6..0000000 --- a/sqlite/tool/memleak.awk +++ /dev/null @@ -1,29 +0,0 @@ -# -# This script looks for memory leaks by analyzing the output of "sqlite" -# when compiled with the SQLITE_DEBUG=2 option. -# -/[0-9]+ malloc / { - mem[$6] = $0 -} -/[0-9]+ realloc / { - mem[$8] = ""; - mem[$10] = $0 -} -/[0-9]+ free / { - if (mem[$6]=="") { - print "*** free without a malloc at",$6 - } - mem[$6] = ""; - str[$6] = "" -} -/^string at / { - addr = $4 - sub("string at " addr " is ","") - str[addr] = $0 -} -END { - for(addr in mem){ - if( mem[addr]=="" ) continue - print mem[addr], str[addr] - } -} diff --git a/sqlite/tool/memleak3.tcl b/sqlite/tool/memleak3.tcl deleted file mode 100644 index f7fa5b4..0000000 --- a/sqlite/tool/memleak3.tcl +++ /dev/null @@ -1,108 +0,0 @@ -#/bin/sh -# \ -exec `which tclsh` $0 "$@" -# -# 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. -###################################################################### - -set doco " -This script is a tool to help track down memory leaks in the sqlite -library. The library must be compiled with the preprocessor symbol -SQLITE_MEMDEBUG set to at least 2. It must be set to 3 to enable stack -traces. - -To use, run the leaky application and save the standard error output. -Then, execute this program with the first argument the name of the -application binary (or interpreter) and the second argument the name of the -text file that contains the collected stderr output. - -If all goes well a summary of unfreed allocations is printed out. If the -GNU C library is in use and SQLITE_DEBUG is 3 or greater a stack trace is -printed out for each unmatched allocation. - -Example: - -$ ./testfixture ../sqlite/test/select1.test 2> memtrace.out -$ tclsh $argv0 ./testfixture memtrace.out -" - -# If stack traces are enabled, the 'addr2line' program is called to -# translate a binary stack address into a human-readable form. -set addr2line addr2line - -if { [llength $argv]!=2 } { - puts "Usage: $argv0 " - puts "" - puts [string trim $doco] - exit -1 -} - - -proc process_input {input_file array_name} { - upvar $array_name mem - set input [open $input_file] - - set MALLOC {([[:digit:]]+) malloc ([[:digit:]]+) bytes at 0x([[:xdigit:]]+)} - # set STACK {^[[:digit:]]+: STACK: (.*)$} - set STACK {^STACK: (.*)$} - set FREE {[[:digit:]]+ free ([[:digit:]]+) bytes at 0x([[:xdigit:]]+)} - set REALLOC {([[:digit:]]+) realloc ([[:digit:]]+) to ([[:digit:]]+)} - append REALLOC { bytes at 0x([[:xdigit:]]+) to 0x([[:xdigit:]]+)} - - set stack "" - while { ![eof $input] } { - set line [gets $input] - if {[regexp $STACK $line dummy stack]} { - # Do nothing. The variable $stack now stores the hexadecimal stack dump - # for the next malloc() or realloc(). - - } elseif { [regexp $MALLOC $line dummy mallocid bytes addr] } { - # If this is a 'malloc' line, set an entry in the mem array. Each entry - # is a list of length three, the number of bytes allocated , the malloc - # number and the stack dump when it was allocated. - set mem($addr) [list $bytes "malloc $mallocid" $stack] - set stack "" - - } elseif { [regexp $FREE $line dummy bytes addr] } { - # If this is a 'free' line, remove the entry from the mem array. If the - # entry does not exist, or is the wrong number of bytes, announce a - # problem. This is more likely a bug in the regular expressions for - # this script than an SQLite defect. - if { [lindex $mem($addr) 0] != $bytes } { - error "byte count mismatch" - } - unset mem($addr) - - } elseif { [regexp $REALLOC $line dummy mallocid ob b oa a] } { - # If it is a realloc line, remove the old mem entry and add a new one. - unset mem($oa); - set mem($a) [list $b "realloc $mallocid" $stack] - set stack "" - } else { - # puts "REJECT: $line" - } - } - - close $input -} - -process_input [lindex $argv 1] mem -set exe [lindex $argv 0] - -foreach key [array names mem] { - set bytes [lindex $mem($key) 0] - set mallocid [lindex $mem($key) 1] - set stack [lindex $mem($key) 2] - puts "Leaked $bytes bytes at 0x$key: $mallocid" - foreach frame [lrange $stack 1 10] { - foreach {f l} [split [exec $addr2line -f --exe=$exe $frame] \n] {} - puts [format "%-30s %s" $f $l] - } - if {[llength $stack]>0 } {puts ""} -} - diff --git a/sqlite/tool/mkkeywordhash.c b/sqlite/tool/mkkeywordhash.c deleted file mode 100644 index 265e3d1..0000000 --- a/sqlite/tool/mkkeywordhash.c +++ /dev/null @@ -1,486 +0,0 @@ -/* -** Compile and run this standalone program in order to generate code that -** implements a function that will translate alphabetic identifiers into -** parser token codes. -*/ -#include -#include -#include - -/* -** All the keywords of the SQL language are stored as in a hash -** table composed of instances of the following structure. -*/ -typedef struct Keyword Keyword; -struct Keyword { - char *zName; /* The keyword name */ - char *zTokenType; /* Token value for this keyword */ - int mask; /* Code this keyword if non-zero */ - int id; /* Unique ID for this record */ - int hash; /* Hash on the keyword */ - int offset; /* Offset to start of name string */ - int len; /* Length of this keyword, not counting final \000 */ - int prefix; /* Number of characters in prefix */ - int iNext; /* Index in aKeywordTable[] of next with same hash */ - int substrId; /* Id to another keyword this keyword is embedded in */ - int substrOffset; /* Offset into substrId for start of this keyword */ -}; - -/* -** Define masks used to determine which keywords are allowed -*/ -#ifdef SQLITE_OMIT_ALTERTABLE -# define ALTER 0 -#else -# define ALTER 1 -#endif -#define ALWAYS 2 -#ifdef SQLITE_OMIT_ATTACH -# define ATTACH 0 -#else -# define ATTACH 4 -#endif -#ifdef SQLITE_OMIT_AUTOINCREMENT -# define AUTOINCR 0 -#else -# define AUTOINCR 8 -#endif -#ifdef SQLITE_OMIT_COMPOUND_SELECT -# define COMPOUND 0 -#else -# define COMPOUND 16 -#endif -#ifdef SQLITE_OMIT_CONFLICT_CLAUSE -# define CONFLICT 0 -#else -# define CONFLICT 32 -#endif -#ifdef SQLITE_OMIT_EXPLAIN -# define EXPLAIN 0 -#else -# define EXPLAIN 128 -#endif -#ifdef SQLITE_OMIT_FOREIGN_KEY -# define FKEY 0 -#else -# define FKEY 256 -#endif -#ifdef SQLITE_OMIT_PRAGMA -# define PRAGMA 0 -#else -# define PRAGMA 512 -#endif -#ifdef SQLITE_OMIT_REINDEX -# define REINDEX 0 -#else -# define REINDEX 1024 -#endif -#ifdef SQLITE_OMIT_SUBQUERY -# define SUBQUERY 0 -#else -# define SUBQUERY 2048 -#endif -#ifdef SQLITE_OMIT_TRIGGER -# define TRIGGER 0 -#else -# define TRIGGER 4096 -#endif -#ifdef SQLITE_OMIT_VACUUM -# define VACUUM 0 -#else -# define VACUUM 8192 -#endif -#ifdef SQLITE_OMIT_VIEW -# define VIEW 0 -#else -# define VIEW 16384 -#endif - - -/* -** These are the keywords -*/ -static Keyword aKeywordTable[] = { - { "ABORT", "TK_ABORT", CONFLICT|TRIGGER }, - { "AFTER", "TK_AFTER", TRIGGER }, - { "ALL", "TK_ALL", ALWAYS }, - { "ALTER", "TK_ALTER", ALTER }, - { "AND", "TK_AND", ALWAYS }, - { "AS", "TK_AS", ALWAYS }, - { "ASC", "TK_ASC", ALWAYS }, - { "ATTACH", "TK_ATTACH", ATTACH }, - { "AUTOINCREMENT", "TK_AUTOINCR", AUTOINCR }, - { "BEFORE", "TK_BEFORE", TRIGGER }, - { "BEGIN", "TK_BEGIN", ALWAYS }, - { "BETWEEN", "TK_BETWEEN", ALWAYS }, - { "BY", "TK_BY", ALWAYS }, - { "CASCADE", "TK_CASCADE", FKEY }, - { "CASE", "TK_CASE", ALWAYS }, - { "CHECK", "TK_CHECK", ALWAYS }, - { "COLLATE", "TK_COLLATE", ALWAYS }, - { "COMMIT", "TK_COMMIT", ALWAYS }, - { "CONFLICT", "TK_CONFLICT", CONFLICT }, - { "CONSTRAINT", "TK_CONSTRAINT", ALWAYS }, - { "CREATE", "TK_CREATE", ALWAYS }, - { "CROSS", "TK_JOIN_KW", ALWAYS }, - { "CURRENT_DATE", "TK_CDATE", ALWAYS }, - { "CURRENT_TIME", "TK_CTIME", ALWAYS }, - { "CURRENT_TIMESTAMP","TK_CTIMESTAMP", ALWAYS }, - { "DATABASE", "TK_DATABASE", ATTACH }, - { "DEFAULT", "TK_DEFAULT", ALWAYS }, - { "DEFERRED", "TK_DEFERRED", ALWAYS }, - { "DEFERRABLE", "TK_DEFERRABLE", FKEY }, - { "DELETE", "TK_DELETE", ALWAYS }, - { "DESC", "TK_DESC", ALWAYS }, - { "DETACH", "TK_DETACH", ATTACH }, - { "DISTINCT", "TK_DISTINCT", ALWAYS }, - { "DROP", "TK_DROP", ALWAYS }, - { "END", "TK_END", ALWAYS }, - { "EACH", "TK_EACH", TRIGGER }, - { "ELSE", "TK_ELSE", ALWAYS }, - { "ESCAPE", "TK_ESCAPE", ALWAYS }, - { "EXCEPT", "TK_EXCEPT", COMPOUND }, - { "EXCLUSIVE", "TK_EXCLUSIVE", ALWAYS }, - { "EXISTS", "TK_EXISTS", SUBQUERY }, - { "EXPLAIN", "TK_EXPLAIN", EXPLAIN }, - { "FAIL", "TK_FAIL", CONFLICT|TRIGGER }, - { "FOR", "TK_FOR", TRIGGER }, - { "FOREIGN", "TK_FOREIGN", FKEY }, - { "FROM", "TK_FROM", ALWAYS }, - { "FULL", "TK_JOIN_KW", ALWAYS }, - { "GLOB", "TK_GLOB", ALWAYS }, - { "GROUP", "TK_GROUP", ALWAYS }, - { "HAVING", "TK_HAVING", ALWAYS }, - { "IGNORE", "TK_IGNORE", CONFLICT|TRIGGER }, - { "IMMEDIATE", "TK_IMMEDIATE", ALWAYS }, - { "IN", "TK_IN", ALWAYS }, - { "INDEX", "TK_INDEX", ALWAYS }, - { "INITIALLY", "TK_INITIALLY", FKEY }, - { "INNER", "TK_JOIN_KW", ALWAYS }, - { "INSERT", "TK_INSERT", ALWAYS }, - { "INSTEAD", "TK_INSTEAD", TRIGGER }, - { "INTERSECT", "TK_INTERSECT", COMPOUND }, - { "INTO", "TK_INTO", ALWAYS }, - { "IS", "TK_IS", ALWAYS }, - { "ISNULL", "TK_ISNULL", ALWAYS }, - { "JOIN", "TK_JOIN", ALWAYS }, - { "KEY", "TK_KEY", ALWAYS }, - { "LEFT", "TK_JOIN_KW", ALWAYS }, - { "LIKE", "TK_LIKE", ALWAYS }, - { "LIMIT", "TK_LIMIT", ALWAYS }, - { "MATCH", "TK_MATCH", ALWAYS }, - { "NATURAL", "TK_JOIN_KW", ALWAYS }, - { "NOT", "TK_NOT", ALWAYS }, - { "NOTNULL", "TK_NOTNULL", ALWAYS }, - { "NULL", "TK_NULL", ALWAYS }, - { "OF", "TK_OF", ALWAYS }, - { "OFFSET", "TK_OFFSET", ALWAYS }, - { "ON", "TK_ON", ALWAYS }, - { "OR", "TK_OR", ALWAYS }, - { "ORDER", "TK_ORDER", ALWAYS }, - { "OUTER", "TK_JOIN_KW", ALWAYS }, - { "PRAGMA", "TK_PRAGMA", PRAGMA }, - { "PRIMARY", "TK_PRIMARY", ALWAYS }, - { "RAISE", "TK_RAISE", TRIGGER }, - { "REFERENCES", "TK_REFERENCES", FKEY }, - { "REINDEX", "TK_REINDEX", REINDEX }, - { "RENAME", "TK_RENAME", ALTER }, - { "REPLACE", "TK_REPLACE", CONFLICT }, - { "RESTRICT", "TK_RESTRICT", FKEY }, - { "RIGHT", "TK_JOIN_KW", ALWAYS }, - { "ROLLBACK", "TK_ROLLBACK", ALWAYS }, - { "ROW", "TK_ROW", TRIGGER }, - { "SELECT", "TK_SELECT", ALWAYS }, - { "SET", "TK_SET", ALWAYS }, - { "STATEMENT", "TK_STATEMENT", TRIGGER }, - { "TABLE", "TK_TABLE", ALWAYS }, - { "TEMP", "TK_TEMP", ALWAYS }, - { "TEMPORARY", "TK_TEMP", ALWAYS }, - { "THEN", "TK_THEN", ALWAYS }, - { "TO", "TK_TO", ALTER }, - { "TRANSACTION", "TK_TRANSACTION", ALWAYS }, - { "TRIGGER", "TK_TRIGGER", TRIGGER }, - { "UNION", "TK_UNION", COMPOUND }, - { "UNIQUE", "TK_UNIQUE", ALWAYS }, - { "UPDATE", "TK_UPDATE", ALWAYS }, - { "USING", "TK_USING", ALWAYS }, - { "VACUUM", "TK_VACUUM", VACUUM }, - { "VALUES", "TK_VALUES", ALWAYS }, - { "VIEW", "TK_VIEW", VIEW }, - { "WHEN", "TK_WHEN", ALWAYS }, - { "WHERE", "TK_WHERE", ALWAYS }, -}; - -/* Number of keywords */ -static int NKEYWORD = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0])); - -/* 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 - -/* -** Comparision function for two Keyword records -*/ -static int keywordCompare1(const void *a, const void *b){ - const Keyword *pA = (Keyword*)a; - const Keyword *pB = (Keyword*)b; - int n = pA->len - pB->len; - if( n==0 ){ - n = strcmp(pA->zName, pB->zName); - } - return n; -} -static int keywordCompare2(const void *a, const void *b){ - const Keyword *pA = (Keyword*)a; - const Keyword *pB = (Keyword*)b; - int n = strcmp(pA->zName, pB->zName); - return n; -} -static int keywordCompare3(const void *a, const void *b){ - const Keyword *pA = (Keyword*)a; - const Keyword *pB = (Keyword*)b; - int n = pA->offset - pB->offset; - return n; -} - -/* -** Return a KeywordTable entry with the given id -*/ -static Keyword *findById(int id){ - int i; - for(i=0; ilen = strlen(p->zName); - p->hash = (UpperToLower[p->zName[0]]*4) ^ - (UpperToLower[p->zName[p->len-1]]*3) ^ p->len; - p->id = i+1; - } - - /* Sort the table from shortest to longest keyword */ - qsort(aKeywordTable, NKEYWORD, sizeof(aKeywordTable[0]), keywordCompare1); - - /* Look for short keywords embedded in longer keywords */ - for(i=NKEYWORD-2; i>=0; i--){ - Keyword *p = &aKeywordTable[i]; - for(j=NKEYWORD-1; j>i && p->substrId==0; j--){ - Keyword *pOther = &aKeywordTable[j]; - if( pOther->substrId ) continue; - if( pOther->len<=p->len ) continue; - for(k=0; k<=pOther->len-p->len; k++){ - if( memcmp(p->zName, &pOther->zName[k], p->len)==0 ){ - p->substrId = pOther->id; - p->substrOffset = k; - break; - } - } - } - } - - /* Sort the table into alphabetical order */ - qsort(aKeywordTable, NKEYWORD, sizeof(aKeywordTable[0]), keywordCompare2); - - /* Fill in the offset for all entries */ - nChar = 0; - for(i=0; ioffset>0 || p->substrId ) continue; - p->offset = nChar; - nChar += p->len; - for(k=p->len-1; k>=1; k--){ - for(j=i+1; joffset>0 || pOther->substrId ) continue; - if( pOther->len<=k ) continue; - if( memcmp(&p->zName[p->len-k], pOther->zName, k)==0 ){ - p = pOther; - p->offset = nChar - k; - nChar = p->offset + p->len; - p->zName += k; - p->len -= k; - p->prefix = k; - j = i; - k = p->len; - } - } - } - } - for(i=0; isubstrId ){ - p->offset = findById(p->substrId)->offset + p->substrOffset; - } - } - - /* Sort the table by offset */ - qsort(aKeywordTable, NKEYWORD, sizeof(aKeywordTable[0]), keywordCompare3); - - /* Figure out how big to make the hash table in order to minimize the - ** number of collisions */ - bestSize = NKEYWORD; - bestCount = NKEYWORD*NKEYWORD; - for(i=NKEYWORD/2; i<=2*NKEYWORD; i++){ - for(j=0; jsubstrId ) continue; - if( j==0 ) printf(" \""); - printf("%s", p->zName); - j += p->len; - if( j>60 ){ - printf("\"\n"); - j = 0; - } - } - printf("%s;\n", j>0 ? "\"" : " "); - - printf(" static const unsigned char aHash[%d] = {\n", bestSize); - for(i=j=0; i12 ){ - printf("\n"); - j = 0; - } - } - printf("%s };\n", j==0 ? "" : "\n"); - - printf(" static const unsigned char aNext[%d] = {\n", NKEYWORD); - for(i=j=0; i12 ){ - printf("\n"); - j = 0; - } - } - printf("%s };\n", j==0 ? "" : "\n"); - - printf(" static const unsigned char aLen[%d] = {\n", NKEYWORD); - for(i=j=0; i12 ){ - printf("\n"); - j = 0; - } - } - printf("%s };\n", j==0 ? "" : "\n"); - - printf(" static const unsigned short int aOffset[%d] = {\n", NKEYWORD); - for(i=j=0; i12 ){ - printf("\n"); - j = 0; - } - } - printf("%s };\n", j==0 ? "" : "\n"); - - printf(" static const unsigned char aCode[%d] = {\n", NKEYWORD); - for(i=j=0; i=5 ){ - printf("\n"); - j = 0; - } - } - printf("%s };\n", j==0 ? "" : "\n"); - - printf(" int h, i;\n"); - printf(" if( n<2 ) return TK_ID;\n"); - printf(" h = ((sqlite3UpperToLower[((unsigned char*)z)[0]]*4) ^\n" - " (sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3) ^\n" - " n) %% %d;\n", bestSize); - printf(" for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){\n"); - printf(" if( aLen[i]==n &&" - " sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){\n"); - printf(" return aCode[i];\n"); - printf(" }\n"); - printf(" }\n"); - printf(" return TK_ID;\n"); - printf("}\n"); - printf("int sqlite3KeywordCode(const char *z, int n){\n"); - printf(" return keywordCode(z, n);\n"); - printf("}\n"); - - return 0; -} diff --git a/sqlite/tool/spaceanal.tcl b/sqlite/tool/spaceanal.tcl deleted file mode 100644 index be26fe0..0000000 --- a/sqlite/tool/spaceanal.tcl +++ /dev/null @@ -1,801 +0,0 @@ -# Run this TCL script using "testfixture" in order get a report that shows -# how much disk space is used by a particular data to actually store data -# versus how much space is unused. -# - -# Get the name of the database to analyze -# -#set argv $argv0 -if {[llength $argv]!=1} { - puts stderr "Usage: $argv0 database-name" - exit 1 -} -set file_to_analyze [lindex $argv 0] -if {![file exists $file_to_analyze]} { - puts stderr "No such file: $file_to_analyze" - exit 1 -} -if {![file readable $file_to_analyze]} { - puts stderr "File is not readable: $file_to_analyze" - exit 1 -} -if {[file size $file_to_analyze]<512} { - puts stderr "Empty or malformed database: $file_to_analyze" - exit 1 -} - -# Open the database -# -sqlite3 db [lindex $argv 0] -set DB [btree_open [lindex $argv 0] 1000 0] - -# In-memory database for collecting statistics. This script loops through -# the tables and indices in the database being analyzed, adding a row for each -# to an in-memory database (for which the schema is shown below). It then -# queries the in-memory db to produce the space-analysis report. -# -sqlite3 mem :memory: -set tabledef\ -{CREATE TABLE space_used( - name clob, -- Name of a table or index in the database file - tblname clob, -- Name of associated table - is_index boolean, -- TRUE if it is an index, false for a table - nentry int, -- Number of entries in the BTree - leaf_entries int, -- Number of leaf entries - payload int, -- Total amount of data stored in this table or index - ovfl_payload int, -- Total amount of data stored on overflow pages - ovfl_cnt int, -- Number of entries that use overflow - mx_payload int, -- Maximum payload size - int_pages int, -- Number of interior pages used - leaf_pages int, -- Number of leaf pages used - ovfl_pages int, -- Number of overflow pages used - int_unused int, -- Number of unused bytes on interior pages - leaf_unused int, -- Number of unused bytes on primary pages - ovfl_unused int -- Number of unused bytes on overflow pages -);} -mem eval $tabledef - -proc integerify {real} { - return [expr int($real)] -} -mem function int integerify - -# Quote a string for use in an SQL query. Examples: -# -# [quote {hello world}] == {'hello world'} -# [quote {hello world's}] == {'hello world''s'} -# -proc quote {txt} { - regsub -all ' $txt '' q - return '$q' -} - -# This proc is a wrapper around the btree_cursor_info command. The -# second argument is an open btree cursor returned by [btree_cursor]. -# The first argument is the name of an array variable that exists in -# the scope of the caller. If the third argument is non-zero, then -# info is returned for the page that lies $up entries upwards in the -# tree-structure. (i.e. $up==1 returns the parent page, $up==2 the -# grandparent etc.) -# -# The following entries in that array are filled in with information retrieved -# using [btree_cursor_info]: -# -# $arrayvar(page_no) = The page number -# $arrayvar(entry_no) = The entry number -# $arrayvar(page_entries) = Total number of entries on this page -# $arrayvar(cell_size) = Cell size (local payload + header) -# $arrayvar(page_freebytes) = Number of free bytes on this page -# $arrayvar(page_freeblocks) = Number of free blocks on the page -# $arrayvar(payload_bytes) = Total payload size (local + overflow) -# $arrayvar(header_bytes) = Header size in bytes -# $arrayvar(local_payload_bytes) = Local payload size -# $arrayvar(parent) = Parent page number -# -proc cursor_info {arrayvar csr {up 0}} { - upvar $arrayvar a - foreach [list a(page_no) \ - a(entry_no) \ - a(page_entries) \ - a(cell_size) \ - a(page_freebytes) \ - a(page_freeblocks) \ - a(payload_bytes) \ - a(header_bytes) \ - a(local_payload_bytes) \ - a(parent) ] [btree_cursor_info $csr $up] {} -} - -# Determine the page-size of the database. This global variable is used -# throughout the script. -# -set pageSize [db eval {PRAGMA page_size}] - -# Analyze every table in the database, one at a time. -# -# The following query returns the name and root-page of each table in the -# database, including the sqlite_master table. -# -set sql { - SELECT name, rootpage FROM sqlite_master WHERE type='table' - UNION ALL - SELECT 'sqlite_master', 1 - ORDER BY 1 -} -foreach {name rootpage} [db eval $sql] { - puts stderr "Analyzing table $name..." - - # Code below traverses the table being analyzed (table name $name), using the - # btree cursor $cursor. Statistics related to table $name are accumulated in - # the following variables: - # - set total_payload 0 ;# Payload space used by all entries - set total_ovfl 0 ;# Payload space on overflow pages - set unused_int 0 ;# Unused space on interior nodes - set unused_leaf 0 ;# Unused space on leaf nodes - set unused_ovfl 0 ;# Unused space on overflow pages - set cnt_ovfl 0 ;# Number of entries that use overflows - set cnt_leaf_entry 0 ;# Number of leaf entries - set cnt_int_entry 0 ;# Number of interor entries - set mx_payload 0 ;# Maximum payload size - set ovfl_pages 0 ;# Number of overflow pages used - set leaf_pages 0 ;# Number of leaf pages - set int_pages 0 ;# Number of interior pages - - # As the btree is traversed, the array variable $seen($pgno) is set to 1 - # the first time page $pgno is encountered. - # - catch {unset seen} - - # The following loop runs once for each entry in table $name. The table - # is traversed using the btree cursor stored in variable $csr - # - set csr [btree_cursor $DB $rootpage 0] - for {btree_first $csr} {![btree_eof $csr]} {btree_next $csr} { - incr cnt_leaf_entry - - # Retrieve information about the entry the btree-cursor points to into - # the array variable $ci (cursor info). - # - cursor_info ci $csr - - # Check if the payload of this entry is greater than the current - # $mx_payload statistic for the table. Also increase the $total_payload - # statistic. - # - if {$ci(payload_bytes)>$mx_payload} {set mx_payload $ci(payload_bytes)} - incr total_payload $ci(payload_bytes) - - # If this entry uses overflow pages, then update the $cnt_ovfl, - # $total_ovfl, $ovfl_pages and $unused_ovfl statistics. - # - set ovfl [expr {$ci(payload_bytes)-$ci(local_payload_bytes)}] - if {$ovfl} { - incr cnt_ovfl - incr total_ovfl $ovfl - set n [expr {int(ceil($ovfl/($pageSize-4.0)))}] - incr ovfl_pages $n - incr unused_ovfl [expr {$n*($pageSize-4) - $ovfl}] - } - - # If this is the first table entry analyzed for the page, then update - # the page-related statistics $leaf_pages and $unused_leaf. Also, if - # this page has a parent page that has not been analyzed, retrieve - # info for the parent and update statistics for it too. - # - if {![info exists seen($ci(page_no))]} { - set seen($ci(page_no)) 1 - incr leaf_pages - incr unused_leaf $ci(page_freebytes) - - # Now check if the page has a parent that has not been analyzed. If - # so, update the $int_pages, $cnt_int_entry and $unused_int statistics - # accordingly. Then check if the parent page has a parent that has - # not yet been analyzed etc. - # - # set parent $ci(parent_page_no) - for {set up 1} \ - {$ci(parent)!=0 && ![info exists seen($ci(parent))]} {incr up} \ - { - # Mark the parent as seen. - # - set seen($ci(parent)) 1 - - # Retrieve info for the parent and update statistics. - cursor_info ci $csr $up - incr int_pages - incr cnt_int_entry $ci(page_entries) - incr unused_int $ci(page_freebytes) - } - } - } - btree_close_cursor $csr - - # Handle the special case where a table contains no data. In this case - # all statistics are zero, except for the number of leaf pages (1) and - # the unused bytes on leaf pages ($pageSize - 8). - # - # An exception to the above is the sqlite_master table. If it is empty - # then all statistics are zero except for the number of leaf pages (1), - # and the number of unused bytes on leaf pages ($pageSize - 112). - # - if {[llength [array names seen]]==0} { - set leaf_pages 1 - if {$rootpage==1} { - set unused_leaf [expr {$pageSize-112}] - } else { - set unused_leaf [expr {$pageSize-8}] - } - } - - # Insert the statistics for the table analyzed into the in-memory database. - # - set sql "INSERT INTO space_used VALUES(" - append sql [quote $name] - append sql ",[quote $name]" - append sql ",0" - append sql ",[expr {$cnt_leaf_entry+$cnt_int_entry}]" - append sql ",$cnt_leaf_entry" - append sql ",$total_payload" - append sql ",$total_ovfl" - append sql ",$cnt_ovfl" - append sql ",$mx_payload" - append sql ",$int_pages" - append sql ",$leaf_pages" - append sql ",$ovfl_pages" - append sql ",$unused_int" - append sql ",$unused_leaf" - append sql ",$unused_ovfl" - append sql ); - mem eval $sql -} - -# Analyze every index in the database, one at a time. -# -# The query below returns the name, associated table and root-page number -# for every index in the database. -# -set sql { - SELECT name, tbl_name, rootpage FROM sqlite_master WHERE type='index' - ORDER BY 2, 1 -} -foreach {name tbl_name rootpage} [db eval $sql] { - puts stderr "Analyzing index $name of table $tbl_name..." - - # Code below traverses the index being analyzed (index name $name), using the - # btree cursor $cursor. Statistics related to index $name are accumulated in - # the following variables: - # - set total_payload 0 ;# Payload space used by all entries - set total_ovfl 0 ;# Payload space on overflow pages - set unused_leaf 0 ;# Unused space on leaf nodes - set unused_ovfl 0 ;# Unused space on overflow pages - set cnt_ovfl 0 ;# Number of entries that use overflows - set cnt_leaf_entry 0 ;# Number of leaf entries - set mx_payload 0 ;# Maximum payload size - set ovfl_pages 0 ;# Number of overflow pages used - set leaf_pages 0 ;# Number of leaf pages - - # As the btree is traversed, the array variable $seen($pgno) is set to 1 - # the first time page $pgno is encountered. - # - catch {unset seen} - - # The following loop runs once for each entry in index $name. The index - # is traversed using the btree cursor stored in variable $csr - # - set csr [btree_cursor $DB $rootpage 0] - for {btree_first $csr} {![btree_eof $csr]} {btree_next $csr} { - incr cnt_leaf_entry - - # Retrieve information about the entry the btree-cursor points to into - # the array variable $ci (cursor info). - # - cursor_info ci $csr - - # Check if the payload of this entry is greater than the current - # $mx_payload statistic for the table. Also increase the $total_payload - # statistic. - # - set payload [btree_keysize $csr] - if {$payload>$mx_payload} {set mx_payload $payload} - incr total_payload $payload - - # If this entry uses overflow pages, then update the $cnt_ovfl, - # $total_ovfl, $ovfl_pages and $unused_ovfl statistics. - # - set ovfl [expr {$payload-$ci(local_payload_bytes)}] - if {$ovfl} { - incr cnt_ovfl - incr total_ovfl $ovfl - set n [expr {int(ceil($ovfl/($pageSize-4.0)))}] - incr ovfl_pages $n - incr unused_ovfl [expr {$n*($pageSize-4) - $ovfl}] - } - - # If this is the first table entry analyzed for the page, then update - # the page-related statistics $leaf_pages and $unused_leaf. - # - if {![info exists seen($ci(page_no))]} { - set seen($ci(page_no)) 1 - incr leaf_pages - incr unused_leaf $ci(page_freebytes) - } - } - btree_close_cursor $csr - - # Handle the special case where a index contains no data. In this case - # all statistics are zero, except for the number of leaf pages (1) and - # the unused bytes on leaf pages ($pageSize - 8). - # - if {[llength [array names seen]]==0} { - set leaf_pages 1 - set unused_leaf [expr {$pageSize-8}] - } - - # Insert the statistics for the index analyzed into the in-memory database. - # - set sql "INSERT INTO space_used VALUES(" - append sql [quote $name] - append sql ",[quote $tbl_name]" - append sql ",1" - append sql ",$cnt_leaf_entry" - append sql ",$cnt_leaf_entry" - append sql ",$total_payload" - append sql ",$total_ovfl" - append sql ",$cnt_ovfl" - append sql ",$mx_payload" - append sql ",0" - append sql ",$leaf_pages" - append sql ",$ovfl_pages" - append sql ",0" - append sql ",$unused_leaf" - append sql ",$unused_ovfl" - append sql ); - mem eval $sql -} - -# Generate a single line of output in the statistics section of the -# report. -# -proc statline {title value {extra {}}} { - set len [string length $title] - set dots [string range {......................................} $len end] - set len [string length $value] - set sp2 [string range { } $len end] - if {$extra ne ""} { - set extra " $extra" - } - puts "$title$dots $value$sp2$extra" -} - -# Generate a formatted percentage value for $num/$denom -# -proc percent {num denom {of {}}} { - if {$denom==0.0} {return ""} - set v [expr {$num*100.0/$denom}] - set of {} - if {$v==1.0 || $v==0.0 || ($v>1.0 && $v<99.0)} { - return [format {%5.1f%% %s} $v $of] - } elseif {$v<0.1 || $v>99.9} { - return [format {%7.3f%% %s} $v $of] - } else { - return [format {%6.2f%% %s} $v $of] - } -} - -proc divide {num denom} { - if {$denom==0} {return 0.0} - return [format %.2f [expr double($num)/double($denom)]] -} - -# Generate a subreport that covers some subset of the database. -# the $where clause determines which subset to analyze. -# -proc subreport {title where} { - global pageSize file_pgcnt - - # Query the in-memory database for the sum of various statistics - # for the subset of tables/indices identified by the WHERE clause in - # $where. Note that even if the WHERE clause matches no rows, the - # following query returns exactly one row (because it is an aggregate). - # - # The results of the query are stored directly by SQLite into local - # variables (i.e. $nentry, $nleaf etc.). - # - mem eval " - SELECT - int(sum(nentry)) AS nentry, - int(sum(leaf_entries)) AS nleaf, - int(sum(payload)) AS payload, - int(sum(ovfl_payload)) AS ovfl_payload, - max(mx_payload) AS mx_payload, - int(sum(ovfl_cnt)) as ovfl_cnt, - int(sum(leaf_pages)) AS leaf_pages, - int(sum(int_pages)) AS int_pages, - int(sum(ovfl_pages)) AS ovfl_pages, - int(sum(leaf_unused)) AS leaf_unused, - int(sum(int_unused)) AS int_unused, - int(sum(ovfl_unused)) AS ovfl_unused - FROM space_used WHERE $where" {} {} - - # Output the sub-report title, nicely decorated with * characters. - # - puts "" - set len [string length $title] - set stars [string repeat * [expr 65-$len]] - puts "*** $title $stars" - puts "" - - # Calculate statistics and store the results in TCL variables, as follows: - # - # total_pages: Database pages consumed. - # total_pages_percent: Pages consumed as a percentage of the file. - # storage: Bytes consumed. - # payload_percent: Payload bytes used as a percentage of $storage. - # total_unused: Unused bytes on pages. - # avg_payload: Average payload per btree entry. - # avg_fanout: Average fanout for internal pages. - # avg_unused: Average unused bytes per btree entry. - # ovfl_cnt_percent: Percentage of btree entries that use overflow pages. - # - set total_pages [expr {$leaf_pages+$int_pages+$ovfl_pages}] - set total_pages_percent [percent $total_pages $file_pgcnt] - set storage [expr {$total_pages*$pageSize}] - set payload_percent [percent $payload $storage {of storage consumed}] - set total_unused [expr {$ovfl_unused+$int_unused+$leaf_unused}] - set avg_payload [divide $payload $nleaf] - set avg_unused [divide $total_unused $nleaf] - if {$int_pages>0} { - # TODO: Is this formula correct? - set nTab [mem eval " - SELECT count(*) FROM ( - SELECT DISTINCT tblname FROM space_used WHERE $where AND is_index=0 - ) - "] - set avg_fanout [mem eval " - SELECT (sum(leaf_pages+int_pages)-$nTab)/sum(int_pages) FROM space_used - WHERE $where AND is_index = 0 - "] - set avg_fanout [format %.2f $avg_fanout] - } - set ovfl_cnt_percent [percent $ovfl_cnt $nleaf {of all entries}] - - # Print out the sub-report statistics. - # - statline {Percentage of total database} $total_pages_percent - statline {Number of entries} $nleaf - statline {Bytes of storage consumed} $storage - statline {Bytes of payload} $payload $payload_percent - statline {Average payload per entry} $avg_payload - statline {Average unused bytes per entry} $avg_unused - if {[info exists avg_fanout]} { - statline {Average fanout} $avg_fanout - } - statline {Maximum payload per entry} $mx_payload - statline {Entries that use overflow} $ovfl_cnt $ovfl_cnt_percent - if {$int_pages>0} { - statline {Index pages used} $int_pages - } - statline {Primary pages used} $leaf_pages - statline {Overflow pages used} $ovfl_pages - statline {Total pages used} $total_pages - if {$int_unused>0} { - set int_unused_percent \ - [percent $int_unused [expr {$int_pages*$pageSize}] {of index space}] - statline "Unused bytes on index pages" $int_unused $int_unused_percent - } - statline "Unused bytes on primary pages" $leaf_unused \ - [percent $leaf_unused [expr {$leaf_pages*$pageSize}] {of primary space}] - statline "Unused bytes on overflow pages" $ovfl_unused \ - [percent $ovfl_unused [expr {$ovfl_pages*$pageSize}] {of overflow space}] - statline "Unused bytes on all pages" $total_unused \ - [percent $total_unused $storage {of all space}] - return 1 -} - -# Calculate the overhead in pages caused by auto-vacuum. -# -# This procedure calculates and returns the number of pages used by the -# auto-vacuum 'pointer-map'. If the database does not support auto-vacuum, -# then 0 is returned. The two arguments are the size of the database file in -# pages and the page size used by the database (in bytes). -proc autovacuum_overhead {filePages pageSize} { - - # Read the value of meta 4. If non-zero, then the database supports - # auto-vacuum. It would be possible to use "PRAGMA auto_vacuum" instead, - # but that would not work if the SQLITE_OMIT_PRAGMA macro was defined - # when the library was built. - set meta4 [lindex [btree_get_meta $::DB] 4] - - # If the database is not an auto-vacuum database or the file consists - # of one page only then there is no overhead for auto-vacuum. Return zero. - if {0==$meta4 || $filePages==1} { - return 0 - } - - # The number of entries on each pointer map page. The layout of the - # database file is one pointer-map page, followed by $ptrsPerPage other - # pages, followed by a pointer-map page etc. The first pointer-map page - # is the second page of the file overall. - set ptrsPerPage [expr double($pageSize/5)] - - # Return the number of pointer map pages in the database. - return [expr int(ceil( ($filePages-1.0)/($ptrsPerPage+1.0) ))] -} - - -# Calculate the summary statistics for the database and store the results -# in TCL variables. They are output below. Variables are as follows: -# -# pageSize: Size of each page in bytes. -# file_bytes: File size in bytes. -# file_pgcnt: Number of pages in the file. -# file_pgcnt2: Number of pages in the file (calculated). -# av_pgcnt: Pages consumed by the auto-vacuum pointer-map. -# av_percent: Percentage of the file consumed by auto-vacuum pointer-map. -# inuse_pgcnt: Data pages in the file. -# inuse_percent: Percentage of pages used to store data. -# free_pgcnt: Free pages calculated as ( - ) -# free_pgcnt2: Free pages in the file according to the file header. -# free_percent: Percentage of file consumed by free pages (calculated). -# free_percent2: Percentage of file consumed by free pages (header). -# ntable: Number of tables in the db. -# nindex: Number of indices in the db. -# nautoindex: Number of indices created automatically. -# nmanindex: Number of indices created manually. -# user_payload: Number of bytes of payload in table btrees -# (not including sqlite_master) -# user_percent: $user_payload as a percentage of total file size. - -set file_bytes [file size $file_to_analyze] -set file_pgcnt [expr {$file_bytes/$pageSize}] - -set av_pgcnt [autovacuum_overhead $file_pgcnt $pageSize] -set av_percent [percent $av_pgcnt $file_pgcnt] - -set sql {SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM space_used} -set inuse_pgcnt [expr int([mem eval $sql])] -set inuse_percent [percent $inuse_pgcnt $file_pgcnt] - -set free_pgcnt [expr $file_pgcnt-$inuse_pgcnt-$av_pgcnt] -set free_percent [percent $free_pgcnt $file_pgcnt] -set free_pgcnt2 [lindex [btree_get_meta $DB] 0] -set free_percent2 [percent $free_pgcnt2 $file_pgcnt] - -set file_pgcnt2 [expr {$inuse_pgcnt+$free_pgcnt2+$av_pgcnt}] - -set ntable [db eval {SELECT count(*)+1 FROM sqlite_master WHERE type='table'}] -set nindex [db eval {SELECT count(*) FROM sqlite_master WHERE type='index'}] -set sql {SELECT count(*) FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'} -set nautoindex [db eval $sql] -set nmanindex [expr {$nindex-$nautoindex}] - -# set total_payload [mem eval "SELECT sum(payload) FROM space_used"] -set user_payload [mem one {SELECT int(sum(payload)) FROM space_used - WHERE NOT is_index AND name NOT LIKE 'sqlite_master'}] -set user_percent [percent $user_payload $file_bytes] - -# Output the summary statistics calculated above. -# -puts "/** Disk-Space Utilization Report For $file_to_analyze" -puts "*** As of [clock format [clock seconds] -format {%Y-%b-%d %H:%M:%S}]" -puts "" -statline {Page size in bytes} $pageSize -statline {Pages in the whole file (measured)} $file_pgcnt -statline {Pages in the whole file (calculated)} $file_pgcnt2 -statline {Pages that store data} $inuse_pgcnt $inuse_percent -statline {Pages on the freelist (per header)} $free_pgcnt2 $free_percent2 -statline {Pages on the freelist (calculated)} $free_pgcnt $free_percent -statline {Pages of auto-vacuum overhead} $av_pgcnt $av_percent -statline {Number of tables in the database} $ntable -statline {Number of indices} $nindex -statline {Number of named indices} $nmanindex -statline {Automatically generated indices} $nautoindex -statline {Size of the file in bytes} $file_bytes -statline {Bytes of user payload stored} $user_payload $user_percent - -# Output table rankings -# -puts "" -puts "*** Page counts for all tables with their indices ********************" -puts "" -mem eval {SELECT tblname, count(*) AS cnt, - int(sum(int_pages+leaf_pages+ovfl_pages)) AS size - FROM space_used GROUP BY tblname ORDER BY size DESC, tblname} {} { - statline [string toupper $tblname] $size [percent $size $file_pgcnt] -} - -# Output subreports -# -if {$nindex>0} { - subreport {All tables and indices} 1 -} -subreport {All tables} {NOT is_index} -if {$nindex>0} { - subreport {All indices} {is_index} -} -foreach tbl [mem eval {SELECT name FROM space_used WHERE NOT is_index - ORDER BY name}] { - regsub ' $tbl '' qn - set name [string toupper $tbl] - set n [mem eval "SELECT count(*) FROM space_used WHERE tblname='$qn'"] - if {$n>1} { - subreport "Table $name and all its indices" "tblname='$qn'" - subreport "Table $name w/o any indices" "name='$qn'" - subreport "Indices of table $name" "tblname='$qn' AND is_index" - } else { - subreport "Table $name" "name='$qn'" - } -} - -# Output instructions on what the numbers above mean. -# -puts { -*** Definitions ****************************************************** - -Page size in bytes - - The number of bytes in a single page of the database file. - Usually 1024. - -Number of pages in the whole file -} -puts \ -" The number of $pageSize-byte pages that go into forming the complete - database" -puts \ -{ -Pages that store data - - The number of pages that store data, either as primary B*Tree pages or - as overflow pages. The number at the right is the data pages divided by - the total number of pages in the file. - -Pages on the freelist - - The number of pages that are not currently in use but are reserved for - future use. The percentage at the right is the number of freelist pages - divided by the total number of pages in the file. - -Pages of auto-vacuum overhead - - The number of pages that store data used by the database to facilitate - auto-vacuum. This is zero for databases that do not support auto-vacuum. - -Number of tables in the database - - The number of tables in the database, including the SQLITE_MASTER table - used to store schema information. - -Number of indices - - The total number of indices in the database. - -Number of named indices - - The number of indices created using an explicit CREATE INDEX statement. - -Automatically generated indices - - The number of indices used to implement PRIMARY KEY or UNIQUE constraints - on tables. - -Size of the file in bytes - - The total amount of disk space used by the entire database files. - -Bytes of user payload stored - - The total number of bytes of user payload stored in the database. The - schema information in the SQLITE_MASTER table is not counted when - computing this number. The percentage at the right shows the payload - divided by the total file size. - -Percentage of total database - - The amount of the complete database file that is devoted to storing - information described by this category. - -Number of entries - - The total number of B-Tree key/value pairs stored under this category. - -Bytes of storage consumed - - The total amount of disk space required to store all B-Tree entries - under this category. The is the total number of pages used times - the pages size. - -Bytes of payload - - The amount of payload stored under this category. Payload is the data - part of table entries and the key part of index entries. The percentage - at the right is the bytes of payload divided by the bytes of storage - consumed. - -Average payload per entry - - The average amount of payload on each entry. This is just the bytes of - payload divided by the number of entries. - -Average unused bytes per entry - - The average amount of free space remaining on all pages under this - category on a per-entry basis. This is the number of unused bytes on - all pages divided by the number of entries. - -Maximum payload per entry - - The largest payload size of any entry. - -Entries that use overflow - - The number of entries that user one or more overflow pages. - -Total pages used - - This is the number of pages used to hold all information in the current - category. This is the sum of index, primary, and overflow pages. - -Index pages used - - This is the number of pages in a table B-tree that hold only key (rowid) - information and no data. - -Primary pages used - - This is the number of B-tree pages that hold both key and data. - -Overflow pages used - - The total number of overflow pages used for this category. - -Unused bytes on index pages - - The total number of bytes of unused space on all index pages. The - percentage at the right is the number of unused bytes divided by the - total number of bytes on index pages. - -Unused bytes on primary pages - - The total number of bytes of unused space on all primary pages. The - percentage at the right is the number of unused bytes divided by the - total number of bytes on primary pages. - -Unused bytes on overflow pages - - The total number of bytes of unused space on all overflow pages. The - percentage at the right is the number of unused bytes divided by the - total number of bytes on overflow pages. - -Unused bytes on all pages - - The total number of bytes of unused space on all primary and overflow - pages. The percentage at the right is the number of unused bytes - divided by the total number of bytes. -} - -# Output a dump of the in-memory database. This can be used for more -# complex offline analysis. -# -puts "**********************************************************************" -puts "The entire text of this report can be sourced into any SQL database" -puts "engine for further analysis. All of the text above is an SQL comment." -puts "The data used to generate this report follows:" -puts "*/" -puts "BEGIN;" -puts $tabledef -unset -nocomplain x -mem eval {SELECT * FROM space_used} x { - puts -nonewline "INSERT INTO space_used VALUES" - set sep ( - foreach col $x(*) { - set v $x($col) - if {$v=="" || ![string is double $v]} {set v [quote $v]} - puts -nonewline $sep$v - set sep , - } - puts ");" -} -puts "COMMIT;" diff --git a/sqlite/www/autoinc.tcl b/sqlite/www/autoinc.tcl deleted file mode 100644 index 9332adc..0000000 --- a/sqlite/www/autoinc.tcl +++ /dev/null @@ -1,109 +0,0 @@ -# -# Run this Tcl script to generate the autoinc.html file. -# -set rcsid {$Id: } -source common.tcl - -if {[llength $argv]>0} { - set outputdir [lindex $argv 0] -} else { - set outputdir "" -} - -header {SQLite Autoincrement} -puts { -

SQLite Autoincrement

- -

-In SQLite, every row of every table has an integer ROWID. -The ROWID for each row is unique among all rows in the same table. -In SQLite version 2.8 the ROWID is a 32-bit signed integer. -Version 3.0 of SQLite expanded the ROWID to be a 64-bit signed integer. -

- -

-You can access the ROWID of an SQLite table using one the special column -names ROWID, _ROWID_, or OID. -Except if you declare an ordinary table column to use one of those special -names, then the use of that name will refer to the declared column not -to the internal ROWID. -

- -

-If a table contains a column of type INTEGER PRIMARY KEY, then that -column becomes an alias for the ROWID. You can then access the ROWID -using any of four different names, the original three names described above -or the name given to the INTEGER PRIMARY KEY column. All these names are -aliases for one another and work equally well in any context. -

- -

-When a new row is inserted into an SQLite table, the ROWID can either -be specified as part of the INSERT statement or it can be assigned -automatically by the database engine. To specify a ROWID manually, -just include it in the list of values to be inserted. For example: -

- -
-CREATE TABLE test1(a INT, b TEXT);
-INSERT INTO test1(rowid, a, b) VALUES(123, 5, 'hello');
-
- -

-If no ROWID is specified on the insert, an appropriate ROWID is created -automatically. The usual algorithm is to give the newly created row -a ROWID that is one larger than the largest ROWID in the table prior -to the insert. If the table is initially empty, then a ROWID of 1 is -used. If the largest ROWID is equal to the largest possible integer -(9223372036854775807 in SQLite version 3.0 and later) then the database -engine starts picking candidate ROWIDs at random until it finds one -that is not previously used. -

- -

-The normal ROWID selection algorithm described above -will generate monotonically increasing -unique ROWIDs as long as you never use the maximum ROWID value and you never -delete the entry in the table with the largest ROWID. -If you ever delete rows or if you ever create a row with the maximum possible -ROWID, then ROWIDs from previously deleted rows might be reused when creating -new rows and newly created ROWIDs might not be in strictly accending order. -

- - -

The AUTOINCREMENT Keyword

- -

-If a column has the type INTEGER PRIMARY KEY AUTOINCREMENT then a slightly -different ROWID selection algorithm is used. -The ROWID chosen for the new row is one larger than the largest ROWID -that has ever before existed in that same table. If the table has never -before contained any data, then a ROWID of 1 is used. If the table -has previously held a row with the largest possible ROWID, then new INSERTs -are not allowed and any attempt to insert a new row will fail with an -SQLITE_FULL error. -

- -

-SQLite keeps track of the largest ROWID that a table has ever held using -the special SQLITE_SEQUENCE table. The SQLITE_SEQUENCE table is created -and initialized automatically whenever a normal table that contains an -AUTOINCREMENT column is created. The content of the SQLITE_SEQUENCE table -can be modified using ordinary UPDATE, INSERT, and DELETE statements. -But making modifications to this table will likely perturb the AUTOINCREMENT -key generation algorithm. Make sure you know what you are doing before -you undertake such changes. -

- -

-The behavior implemented by the AUTOINCREMENT keyword is subtly different -from the default behavior. With AUTOINCREMENT, rows with automatically -selected ROWIDs are guaranteed to have ROWIDs that have never been used -before by the same table in the same database. And the automatically generated -ROWIDs are guaranteed to be monotonically increasing. These are important -properties in certain applications. But if your application does not -need these properties, you should probably stay with the default behavior -since the use of AUTOINCREMENT requires additional work to be done -as each row is inserted and thus causes INSERTs to run a little slower. -} -footer $rcsid diff --git a/sqlite/www/c_interface.tcl b/sqlite/www/c_interface.tcl deleted file mode 100644 index c784ff0..0000000 --- a/sqlite/www/c_interface.tcl +++ /dev/null @@ -1,1116 +0,0 @@ -# -# Run this Tcl script to generate the sqlite.html file. -# -set rcsid {$Id: c_interface.tcl,v 1.43 2004/11/19 11:59:24 danielk1977 Exp $} -source common.tcl -header {The C language interface to the SQLite library} -puts { -

The C language interface to the SQLite library

- -

The SQLite library is designed to be very easy to use from -a C or C++ program. This document gives an overview of the C/C++ -programming interface.

- -

1.0 The Core API

- -

The interface to the SQLite library consists of three core functions, -one opaque data structure, and some constants used as return values. -The core interface is as follows:

- -
-typedef struct sqlite sqlite;
-#define SQLITE_OK           0   /* Successful result */
-
-sqlite *sqlite_open(const char *dbname, int mode, char **errmsg);
-
-void sqlite_close(sqlite *db);
-
-int sqlite_exec(
-  sqlite *db,
-  char *sql,
-  int (*xCallback)(void*,int,char**,char**),
-  void *pArg,
-  char **errmsg
-);
-
- -

-The above is all you really need to know in order to use SQLite -in your C or C++ programs. There are other interface functions -available (and described below) but we will begin by describing -the core functions shown above. -

- - -

1.1 Opening a database

- -

Use the sqlite_open function to open an existing SQLite -database or to create a new SQLite database. The first argument -is the database name. The second argument is intended to signal -whether the database is going to be used for reading and writing -or just for reading. But in the current implementation, the -second argument to sqlite_open is ignored. -The third argument is a pointer to a string pointer. -If the third argument is not NULL and an error occurs -while trying to open the database, then an error message will be -written to memory obtained from malloc() and *errmsg will be made -to point to this error message. The calling function is responsible -for freeing the memory when it has finished with it.

- -

The name of an SQLite database is the name of a file that will -contain the database. If the file does not exist, SQLite attempts -to create and initialize it. If the file is read-only (due to -permission bits or because it is located on read-only media like -a CD-ROM) then SQLite opens the database for reading only. The -entire SQL database is stored in a single file on the disk. But -additional temporary files may be created during the execution of -an SQL command in order to store the database rollback journal or -temporary and intermediate results of a query.

- -

The return value of the sqlite_open function is a -pointer to an opaque sqlite structure. This pointer will -be the first argument to all subsequent SQLite function calls that -deal with the same database. NULL is returned if the open fails -for any reason.

- -
-

1.2 Closing the database

- -

To close an SQLite database, call the sqlite_close -function passing it the sqlite structure pointer that was obtained -from a prior call to sqlite_open. -If a transaction is active when the database is closed, the transaction -is rolled back.

- -
-

1.3 Executing SQL statements

- -

The sqlite_exec function is used to process SQL statements -and queries. This function requires 5 parameters as follows:

- -
    -
  1. A pointer to the sqlite structure obtained from a prior call - to sqlite_open.

  2. -
  3. A null-terminated string containing the text of one or more - SQL statements and/or queries to be processed.

  4. -
  5. A pointer to a callback function which is invoked once for each - row in the result of a query. This argument may be NULL, in which - case no callbacks will ever be invoked.

  6. -
  7. A pointer that is forwarded to become the first argument - to the callback function.

  8. -
  9. A pointer to an error string. Error messages are written to space - obtained from malloc() and the error string is made to point to - the malloced space. The calling function is responsible for freeing - this space when it has finished with it. - This argument may be NULL, in which case error messages are not - reported back to the calling function.

  10. -
- -

-The callback function is used to receive the results of a query. A -prototype for the callback function is as follows:

- -
-int Callback(void *pArg, int argc, char **argv, char **columnNames){
-  return 0;
-}
-
- -
-

The first argument to the callback is just a copy of the fourth argument -to sqlite_exec This parameter can be used to pass arbitrary -information through to the callback function from client code. -The second argument is the number of columns in the query result. -The third argument is an array of pointers to strings where each string -is a single column of the result for that record. Note that the -callback function reports a NULL value in the database as a NULL pointer, -which is very different from an empty string. If the i-th parameter -is an empty string, we will get:

-
-argv[i][0] == 0
-
-

But if the i-th parameter is NULL we will get:

-
-argv[i] == 0
-
- -

The names of the columns are contained in first argc -entries of the fourth argument. -If the SHOW_DATATYPES pragma -is on (it is off by default) then -the second argc entries in the 4th argument are the datatypes -for the corresponding columns. -

- -

If the -EMPTY_RESULT_CALLBACKS pragma is set to ON and the result of -a query is an empty set, then the callback is invoked once with the -third parameter (argv) set to 0. In other words -

-argv == 0
-
-The second parameter (argc) -and the fourth parameter (columnNames) are still valid -and can be used to determine the number and names of the result -columns if there had been a result. -The default behavior is not to invoke the callback at all if the -result set is empty.

- - -

The callback function should normally return 0. If the callback -function returns non-zero, the query is immediately aborted and -sqlite_exec will return SQLITE_ABORT.

- -

1.4 Error Codes

- -

-The sqlite_exec function normally returns SQLITE_OK. But -if something goes wrong it can return a different value to indicate -the type of error. Here is a complete list of the return codes: -

- -
-#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 sqlite_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   /* (Internal Only) Database table 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_ROW         100  /* sqlite_step() has another row ready */
-#define SQLITE_DONE        101  /* sqlite_step() has finished executing */
-
- -

-The meanings of these various return values are as follows: -

- -
-
-
SQLITE_OK
-

This value is returned if everything worked and there were no errors. -

-
SQLITE_INTERNAL
-

This value indicates that an internal consistency check within -the SQLite library failed. This can only happen if there is a bug in -the SQLite library. If you ever get an SQLITE_INTERNAL reply from -an sqlite_exec call, please report the problem on the SQLite -mailing list. -

-
SQLITE_ERROR
-

This return value indicates that there was an error in the SQL -that was passed into the sqlite_exec. -

-
SQLITE_PERM
-

This return value says that the access permissions on the database -file are such that the file cannot be opened. -

-
SQLITE_ABORT
-

This value is returned if the callback function returns non-zero. -

-
SQLITE_BUSY
-

This return code indicates that another program or thread has -the database locked. SQLite allows two or more threads to read the -database at the same time, but only one thread can have the database -open for writing at the same time. Locking in SQLite is on the -entire database.

-

-
SQLITE_LOCKED
-

This return code is similar to SQLITE_BUSY in that it indicates -that the database is locked. But the source of the lock is a recursive -call to sqlite_exec. This return can only occur if you attempt -to invoke sqlite_exec from within a callback routine of a query -from a prior invocation of sqlite_exec. Recursive calls to -sqlite_exec are allowed as long as they do -not attempt to write the same table. -

-
SQLITE_NOMEM
-

This value is returned if a call to malloc fails. -

-
SQLITE_READONLY
-

This return code indicates that an attempt was made to write to -a database file that is opened for reading only. -

-
SQLITE_INTERRUPT
-

This value is returned if a call to sqlite_interrupt -interrupts a database operation in progress. -

-
SQLITE_IOERR
-

This value is returned if the operating system informs SQLite -that it is unable to perform some disk I/O operation. This could mean -that there is no more space left on the disk. -

-
SQLITE_CORRUPT
-

This value is returned if SQLite detects that the database it is -working on has become corrupted. Corruption might occur due to a rogue -process writing to the database file or it might happen due to an -perviously undetected logic error in of SQLite. This value is also -returned if a disk I/O error occurs in such a way that SQLite is forced -to leave the database file in a corrupted state. The latter should only -happen due to a hardware or operating system malfunction. -

-
SQLITE_FULL
-

This value is returned if an insertion failed because there is -no space left on the disk, or the database is too big to hold any -more information. The latter case should only occur for databases -that are larger than 2GB in size. -

-
SQLITE_CANTOPEN
-

This value is returned if the database file could not be opened -for some reason. -

-
SQLITE_PROTOCOL
-

This value is returned if some other process is messing with -file locks and has violated the file locking protocol that SQLite uses -on its rollback journal files. -

-
SQLITE_SCHEMA
-

When the database first opened, SQLite reads the database schema -into memory and uses that schema to parse new SQL statements. If another -process changes the schema, the command currently being processed will -abort because the virtual machine code generated assumed the old -schema. This is the return code for such cases. Retrying the -command usually will clear the problem. -

-
SQLITE_TOOBIG
-

SQLite will not store more than about 1 megabyte of data in a single -row of a single table. If you attempt to store more than 1 megabyte -in a single row, this is the return code you get. -

-
SQLITE_CONSTRAINT
-

This constant is returned if the SQL statement would have violated -a database constraint. -

-
SQLITE_MISMATCH
-

This error occurs when there is an attempt to insert non-integer -data into a column labeled INTEGER PRIMARY KEY. For most columns, SQLite -ignores the data type and allows any kind of data to be stored. But -an INTEGER PRIMARY KEY column is only allowed to store integer data. -

-
SQLITE_MISUSE
-

This error might occur if one or more of the SQLite API routines -is used incorrectly. Examples of incorrect usage include calling -sqlite_exec after the database has been closed using -sqlite_close or -calling sqlite_exec with the same -database pointer simultaneously from two separate threads. -

-
SQLITE_NOLFS
-

This error means that you have attempts to create or access a file -database file that is larger that 2GB on a legacy Unix machine that -lacks large file support. -

-
SQLITE_AUTH
-

This error indicates that the authorizer callback -has disallowed the SQL you are attempting to execute. -

-
SQLITE_ROW
-

This is one of the return codes from the -sqlite_step routine which is part of the non-callback API. -It indicates that another row of result data is available. -

-
SQLITE_DONE
-

This is one of the return codes from the -sqlite_step routine which is part of the non-callback API. -It indicates that the SQL statement has been completely executed and -the sqlite_finalize routine is ready to be called. -

-
-
- -

2.0 Accessing Data Without Using A Callback Function

- -

-The sqlite_exec routine described above used to be the only -way to retrieve data from an SQLite database. But many programmers found -it inconvenient to use a callback function to obtain results. So beginning -with SQLite version 2.7.7, a second access interface is available that -does not use callbacks. -

- -

-The new interface uses three separate functions to replace the single -sqlite_exec function. -

- -
-typedef struct sqlite_vm sqlite_vm;
-
-int sqlite_compile(
-  sqlite *db,              /* The open database */
-  const char *zSql,        /* SQL statement to be compiled */
-  const char **pzTail,     /* OUT: uncompiled tail of zSql */
-  sqlite_vm **ppVm,        /* OUT: the virtual machine to execute zSql */
-  char **pzErrmsg          /* OUT: Error message. */
-);
-
-int sqlite_step(
-  sqlite_vm *pVm,          /* The virtual machine to execute */
-  int *pN,                 /* OUT: Number of columns in result */
-  const char ***pazValue,  /* OUT: Column data */
-  const char ***pazColName /* OUT: Column names and datatypes */
-);
-
-int sqlite_finalize(
-  sqlite_vm *pVm,          /* The virtual machine to be finalized */
-  char **pzErrMsg          /* OUT: Error message */
-);
-
- -

-The strategy is to compile a single SQL statement using -sqlite_compile then invoke sqlite_step multiple times, -once for each row of output, and finally call sqlite_finalize -to clean up after the SQL has finished execution. -

- -

2.1 Compiling An SQL Statement Into A Virtual Machine

- -

-The sqlite_compile "compiles" a single SQL statement (specified -by the second parameter) and generates a virtual machine that is able -to execute that statement. -As with must interface routines, the first parameter must be a pointer -to an sqlite structure that was obtained from a prior call to -sqlite_open. - -

-A pointer to the virtual machine is stored in a pointer which is passed -in as the 4th parameter. -Space to hold the virtual machine is dynamically allocated. To avoid -a memory leak, the calling function must invoke -sqlite_finalize on the virtual machine after it has finished -with it. -The 4th parameter may be set to NULL if an error is encountered during -compilation. -

- -

-If any errors are encountered during compilation, an error message is -written into memory obtained from malloc and the 5th parameter -is made to point to that memory. If the 5th parameter is NULL, then -no error message is generated. If the 5th parameter is not NULL, then -the calling function should dispose of the memory containing the error -message by calling sqlite_freemem. -

- -

-If the 2nd parameter actually contains two or more statements of SQL, -only the first statement is compiled. (This is different from the -behavior of sqlite_exec which executes all SQL statements -in its input string.) The 3rd parameter to sqlite_compile -is made to point to the first character beyond the end of the first -statement of SQL in the input. If the 2nd parameter contains only -a single SQL statement, then the 3rd parameter will be made to point -to the '\000' terminator at the end of the 2nd parameter. -

- -

-On success, sqlite_compile returns SQLITE_OK. -Otherwise and error code is returned. -

- -

2.2 Step-By-Step Execution Of An SQL Statement

- -

-After a virtual machine has been generated using sqlite_compile -it is executed by one or more calls to sqlite_step. Each -invocation of sqlite_step, except the last one, -returns a single row of the result. -The number of columns in the result is stored in the integer that -the 2nd parameter points to. -The pointer specified by the 3rd parameter is made to point -to an array of pointers to column values. -The pointer in the 4th parameter is made to point to an array -of pointers to column names and datatypes. -The 2nd through 4th parameters to sqlite_step convey the -same information as the 2nd through 4th parameters of the -callback routine when using -the sqlite_exec interface. Except, with sqlite_step -the column datatype information is always included in the in the -4th parameter regardless of whether or not the -SHOW_DATATYPES pragma -is on or off. -

- -

-Each invocation of sqlite_step returns an integer code that -indicates what happened during that step. This code may be -SQLITE_BUSY, SQLITE_ROW, SQLITE_DONE, SQLITE_ERROR, or -SQLITE_MISUSE. -

- -

-If the virtual machine is unable to open the database file because -it is locked by another thread or process, sqlite_step -will return SQLITE_BUSY. The calling function should do some other -activity, or sleep, for a short amount of time to give the lock a -chance to clear, then invoke sqlite_step again. This can -be repeated as many times as desired. -

- -

-Whenever another row of result data is available, -sqlite_step will return SQLITE_ROW. The row data is -stored in an array of pointers to strings and the 2nd parameter -is made to point to this array. -

- -

-When all processing is complete, sqlite_step will return -either SQLITE_DONE or SQLITE_ERROR. SQLITE_DONE indicates that the -statement completed successfully and SQLITE_ERROR indicates that there -was a run-time error. (The details of the error are obtained from -sqlite_finalize.) It is a misuse of the library to attempt -to call sqlite_step again after it has returned SQLITE_DONE -or SQLITE_ERROR. -

- -

-When sqlite_step returns SQLITE_DONE or SQLITE_ERROR, -the *pN and *pazColName values are set to the number of columns -in the result set and to the names of the columns, just as they -are for an SQLITE_ROW return. This allows the calling code to -find the number of result columns and the column names and datatypes -even if the result set is empty. The *pazValue parameter is always -set to NULL when the return codes is SQLITE_DONE or SQLITE_ERROR. -If the SQL being executed is a statement that does not -return a result (such as an INSERT or an UPDATE) then *pN will -be set to zero and *pazColName will be set to NULL. -

- -

-If you abuse the library by trying to call sqlite_step -inappropriately it will attempt return SQLITE_MISUSE. -This can happen if you call sqlite_step() on the same virtual machine -at the same -time from two or more threads or if you call sqlite_step() -again after it returned SQLITE_DONE or SQLITE_ERROR or if you -pass in an invalid virtual machine pointer to sqlite_step(). -You should not depend on the SQLITE_MISUSE return code to indicate -an error. It is possible that a misuse of the interface will go -undetected and result in a program crash. The SQLITE_MISUSE is -intended as a debugging aid only - to help you detect incorrect -usage prior to a mishap. The misuse detection logic is not guaranteed -to work in every case. -

- -

2.3 Deleting A Virtual Machine

- -

-Every virtual machine that sqlite_compile creates should -eventually be handed to sqlite_finalize. The sqlite_finalize() -procedure deallocates the memory and other resources that the virtual -machine uses. Failure to call sqlite_finalize() will result in -resource leaks in your program. -

- -

-The sqlite_finalize routine also returns the result code -that indicates success or failure of the SQL operation that the -virtual machine carried out. -The value returned by sqlite_finalize() will be the same as would -have been returned had the same SQL been executed by sqlite_exec. -The error message returned will also be the same. -

- -

-It is acceptable to call sqlite_finalize on a virtual machine -before sqlite_step has returned SQLITE_DONE. Doing so has -the effect of interrupting the operation in progress. Partially completed -changes will be rolled back and the database will be restored to its -original state (unless an alternative recovery algorithm is selected using -an ON CONFLICT clause in the SQL being executed.) The effect is the -same as if a callback function of sqlite_exec had returned -non-zero. -

- -

-It is also acceptable to call sqlite_finalize on a virtual machine -that has never been passed to sqlite_step even once. -

- -

3.0 The Extended API

- -

Only the three core routines described in section 1.0 are required to use -SQLite. But there are many other functions that provide -useful interfaces. These extended routines are as follows: -

- -
-int sqlite_last_insert_rowid(sqlite*);
-
-int sqlite_changes(sqlite*);
-
-int sqlite_get_table(
-  sqlite*,
-  char *sql,
-  char ***result,
-  int *nrow,
-  int *ncolumn,
-  char **errmsg
-);
-
-void sqlite_free_table(char**);
-
-void sqlite_interrupt(sqlite*);
-
-int sqlite_complete(const char *sql);
-
-void sqlite_busy_handler(sqlite*, int (*)(void*,const char*,int), void*);
-
-void sqlite_busy_timeout(sqlite*, int ms);
-
-const char sqlite_version[];
-
-const char sqlite_encoding[];
-
-int sqlite_exec_printf(
-  sqlite*,
-  char *sql,
-  int (*)(void*,int,char**,char**),
-  void*,
-  char **errmsg,
-  ...
-);
-
-int sqlite_exec_vprintf(
-  sqlite*,
-  char *sql,
-  int (*)(void*,int,char**,char**),
-  void*,
-  char **errmsg,
-  va_list
-);
-
-int sqlite_get_table_printf(
-  sqlite*,
-  char *sql,
-  char ***result,
-  int *nrow,
-  int *ncolumn,
-  char **errmsg,
-  ...
-);
-
-int sqlite_get_table_vprintf(
-  sqlite*,
-  char *sql,
-  char ***result,
-  int *nrow,
-  int *ncolumn,
-  char **errmsg,
-  va_list
-);
-
-char *sqlite_mprintf(const char *zFormat, ...);
-
-char *sqlite_vmprintf(const char *zFormat, va_list);
-
-void sqlite_freemem(char*);
-
-void sqlite_progress_handler(sqlite*, int, int (*)(void*), void*);
-
-
- -

All of the above definitions are included in the "sqlite.h" -header file that comes in the source tree.

- -

3.1 The ROWID of the most recent insert

- -

Every row of an SQLite table has a unique integer key. If the -table has a column labeled INTEGER PRIMARY KEY, then that column -serves as the key. If there is no INTEGER PRIMARY KEY column then -the key is a unique integer. The key for a row can be accessed in -a SELECT statement or used in a WHERE or ORDER BY clause using any -of the names "ROWID", "OID", or "_ROWID_".

- -

When you do an insert into a table that does not have an INTEGER PRIMARY -KEY column, or if the table does have an INTEGER PRIMARY KEY but the value -for that column is not specified in the VALUES clause of the insert, then -the key is automatically generated. You can find the value of the key -for the most recent INSERT statement using the -sqlite_last_insert_rowid API function.

- -

3.2 The number of rows that changed

- -

The sqlite_changes API function returns the number of rows -that have been inserted, deleted, or modified since the database was -last quiescent. A "quiescent" database is one in which there are -no outstanding calls to sqlite_exec and no VMs created by -sqlite_compile that have not been finalized by sqlite_finalize. -In common usage, sqlite_changes returns the number -of rows inserted, deleted, or modified by the most recent sqlite_exec -call or since the most recent sqlite_compile. But if you have -nested calls to sqlite_exec (that is, if the callback routine -of one sqlite_exec invokes another sqlite_exec) or if -you invoke sqlite_compile to create a new VM while there is -still another VM in existance, then -the meaning of the number returned by sqlite_changes is more -complex. -The number reported includes any changes -that were later undone by a ROLLBACK or ABORT. But rows that are -deleted because of a DROP TABLE are not counted.

- -

SQLite implements the command "DELETE FROM table" (without -a WHERE clause) by dropping the table then recreating it. -This is much faster than deleting the elements of the table individually. -But it also means that the value returned from sqlite_changes -will be zero regardless of the number of elements that were originally -in the table. If an accurate count of the number of elements deleted -is necessary, use "DELETE FROM table WHERE 1" instead.

- -

3.3 Querying into memory obtained from malloc()

- -

The sqlite_get_table function is a wrapper around -sqlite_exec that collects all the information from successive -callbacks and writes it into memory obtained from malloc(). This -is a convenience function that allows the application to get the -entire result of a database query with a single function call.

- -

The main result from sqlite_get_table is an array of pointers -to strings. There is one element in this array for each column of -each row in the result. NULL results are represented by a NULL -pointer. In addition to the regular data, there is an added row at the -beginning of the array that contains the name of each column of the -result.

- -

As an example, consider the following query:

- -
-SELECT employee_name, login, host FROM users WHERE login LIKE 'd%'; -
- -

This query will return the name, login and host computer name -for every employee whose login begins with the letter "d". If this -query is submitted to sqlite_get_table the result might -look like this:

- -
-nrow = 2
-ncolumn = 3
-result[0] = "employee_name"
-result[1] = "login"
-result[2] = "host"
-result[3] = "dummy"
-result[4] = "No such user"
-result[5] = 0
-result[6] = "D. Richard Hipp"
-result[7] = "drh"
-result[8] = "zadok" -
- -

Notice that the "host" value for the "dummy" record is NULL so -the result[] array contains a NULL pointer at that slot.

- -

If the result set of a query is empty, then by default -sqlite_get_table will set nrow to 0 and leave its -result parameter is set to NULL. But if the EMPTY_RESULT_CALLBACKS -pragma is ON then the result parameter is initialized to the names -of the columns only. For example, consider this query which has -an empty result set:

- -
-SELECT employee_name, login, host FROM users WHERE employee_name IS NULL; -
- -

-The default behavior gives this results: -

- -
-nrow = 0
-ncolumn = 0
-result = 0
-
- -

-But if the EMPTY_RESULT_CALLBACKS pragma is ON, then the following -is returned: -

- -
-nrow = 0
-ncolumn = 3
-result[0] = "employee_name"
-result[1] = "login"
-result[2] = "host"
-
- -

Memory to hold the information returned by sqlite_get_table -is obtained from malloc(). But the calling function should not try -to free this information directly. Instead, pass the complete table -to sqlite_free_table when the table is no longer needed. -It is safe to call sqlite_free_table with a NULL pointer such -as would be returned if the result set is empty.

- -

The sqlite_get_table routine returns the same integer -result code as sqlite_exec.

- -

3.4 Interrupting an SQLite operation

- -

The sqlite_interrupt function can be called from a -different thread or from a signal handler to cause the current database -operation to exit at its first opportunity. When this happens, -the sqlite_exec routine (or the equivalent) that started -the database operation will return SQLITE_INTERRUPT.

- -

3.5 Testing for a complete SQL statement

- -

The next interface routine to SQLite is a convenience function used -to test whether or not a string forms a complete SQL statement. -If the sqlite_complete function returns true when its input -is a string, then the argument forms a complete SQL statement. -There are no guarantees that the syntax of that statement is correct, -but we at least know the statement is complete. If sqlite_complete -returns false, then more text is required to complete the SQL statement.

- -

For the purpose of the sqlite_complete function, an SQL -statement is complete if it ends in a semicolon.

- -

The sqlite command-line utility uses the sqlite_complete -function to know when it needs to call sqlite_exec. After each -line of input is received, sqlite calls sqlite_complete -on all input in its buffer. If sqlite_complete returns true, -then sqlite_exec is called and the input buffer is reset. If -sqlite_complete returns false, then the prompt is changed to -the continuation prompt and another line of text is read and added to -the input buffer.

- -

3.6 Library version string

- -

The SQLite library exports the string constant named -sqlite_version which contains the version number of the -library. The header file contains a macro SQLITE_VERSION -with the same information. If desired, a program can compare -the SQLITE_VERSION macro against the sqlite_version -string constant to verify that the version number of the -header file and the library match.

- -

3.7 Library character encoding

- -

By default, SQLite assumes that all data uses a fixed-size -8-bit character (iso8859). But if you give the --enable-utf8 option -to the configure script, then the library assumes UTF-8 variable -sized characters. This makes a difference for the LIKE and GLOB -operators and the LENGTH() and SUBSTR() functions. The static -string sqlite_encoding will be set to either "UTF-8" or -"iso8859" to indicate how the library was compiled. In addition, -the sqlite.h header file will define one of the -macros SQLITE_UTF8 or SQLITE_ISO8859, as appropriate.

- -

Note that the character encoding mechanism used by SQLite cannot -be changed at run-time. This is a compile-time option only. The -sqlite_encoding character string just tells you how the library -was compiled.

- -

3.8 Changing the library's response to locked files

- -

The sqlite_busy_handler procedure can be used to register -a busy callback with an open SQLite database. The busy callback will -be invoked whenever SQLite tries to access a database that is locked. -The callback will typically do some other useful work, or perhaps sleep, -in order to give the lock a chance to clear. If the callback returns -non-zero, then SQLite tries again to access the database and the cycle -repeats. If the callback returns zero, then SQLite aborts the current -operation and returns SQLITE_BUSY.

- -

The arguments to sqlite_busy_handler are the opaque -structure returned from sqlite_open, a pointer to the busy -callback function, and a generic pointer that will be passed as -the first argument to the busy callback. When SQLite invokes the -busy callback, it sends it three arguments: the generic pointer -that was passed in as the third argument to sqlite_busy_handler, -the name of the database table or index that the library is trying -to access, and the number of times that the library has attempted to -access the database table or index.

- -

For the common case where we want the busy callback to sleep, -the SQLite library provides a convenience routine sqlite_busy_timeout. -The first argument to sqlite_busy_timeout is a pointer to -an open SQLite database and the second argument is a number of milliseconds. -After sqlite_busy_timeout has been executed, the SQLite library -will wait for the lock to clear for at least the number of milliseconds -specified before it returns SQLITE_BUSY. Specifying zero milliseconds for -the timeout restores the default behavior.

- -

3.9 Using the _printf() wrapper functions

- -

The four utility functions

- -

-

    -
  • sqlite_exec_printf()
  • -
  • sqlite_exec_vprintf()
  • -
  • sqlite_get_table_printf()
  • -
  • sqlite_get_table_vprintf()
  • -
-

- -

implement the same query functionality as sqlite_exec -and sqlite_get_table. But instead of taking a complete -SQL statement as their second argument, the four _printf -routines take a printf-style format string. The SQL statement to -be executed is generated from this format string and from whatever -additional arguments are attached to the end of the function call.

- -

There are two advantages to using the SQLite printf -functions instead of sprintf. First of all, with the -SQLite printf routines, there is never a danger of overflowing a -static buffer as there is with sprintf. The SQLite -printf routines automatically allocate (and later frees) -as much memory as is -necessary to hold the SQL statements generated.

- -

The second advantage the SQLite printf routines have over -sprintf are two new formatting options specifically designed -to support string literals in SQL. Within the format string, -the %q formatting option works very much like %s in that it -reads a null-terminated string from the argument list and inserts -it into the result. But %q translates the inserted string by -making two copies of every single-quote (') character in the -substituted string. This has the effect of escaping the end-of-string -meaning of single-quote within a string literal. The %Q formatting -option works similar; it translates the single-quotes like %q and -additionally encloses the resulting string in single-quotes. -If the argument for the %Q formatting options is a NULL pointer, -the resulting string is NULL without single quotes. -

- -

Consider an example. Suppose you are trying to insert a string -value into a database table where the string value was obtained from -user input. Suppose the string to be inserted is stored in a variable -named zString. The code to do the insertion might look like this:

- -
-sqlite_exec_printf(db,
-  "INSERT INTO table1 VALUES('%s')",
-  0, 0, 0, zString);
-
- -

If the zString variable holds text like "Hello", then this statement -will work just fine. But suppose the user enters a string like -"Hi y'all!". The SQL statement generated reads as follows: - -

-INSERT INTO table1 VALUES('Hi y'all')
-
- -

This is not valid SQL because of the apostrophy in the word "y'all". -But if the %q formatting option is used instead of %s, like this:

- -
-sqlite_exec_printf(db,
-  "INSERT INTO table1 VALUES('%q')",
-  0, 0, 0, zString);
-
- -

Then the generated SQL will look like the following:

- -
-INSERT INTO table1 VALUES('Hi y''all')
-
- -

Here the apostrophy has been escaped and the SQL statement is well-formed. -When generating SQL on-the-fly from data that might contain a -single-quote character ('), it is always a good idea to use the -SQLite printf routines and the %q formatting option instead of sprintf. -

- -

If the %Q formatting option is used instead of %q, like this:

- -
-sqlite_exec_printf(db,
-  "INSERT INTO table1 VALUES(%Q)",
-  0, 0, 0, zString);
-
- -

Then the generated SQL will look like the following:

- -
-INSERT INTO table1 VALUES('Hi y''all')
-
- -

If the value of the zString variable is NULL, the generated SQL -will look like the following:

- -
-INSERT INTO table1 VALUES(NULL)
-
- -

All of the _printf() routines above are built around the following -two functions:

- -
-char *sqlite_mprintf(const char *zFormat, ...);
-char *sqlite_vmprintf(const char *zFormat, va_list);
-
- -

The sqlite_mprintf() routine works like the the standard library -sprintf() except that it writes its results into memory obtained -from malloc() and returns a pointer to the malloced buffer. -sqlite_mprintf() also understands the %q and %Q extensions described -above. The sqlite_vmprintf() is a varargs version of the same -routine. The string pointer that these routines return should be freed -by passing it to sqlite_freemem(). -

- -

3.10 Performing background jobs during large queries

- -

The sqlite_progress_handler() routine can be used to register a -callback routine with an SQLite database to be invoked periodically during long -running calls to sqlite_exec(), sqlite_step() and the various -wrapper functions. -

- -

The callback is invoked every N virtual machine operations, where N is -supplied as the second argument to sqlite_progress_handler(). The third -and fourth arguments to sqlite_progress_handler() are a pointer to the -routine to be invoked and a void pointer to be passed as the first argument to -it. -

- -

The time taken to execute each virtual machine operation can vary based on -many factors. A typical value for a 1 GHz PC is between half and three million -per second but may be much higher or lower, depending on the query. As such it -is difficult to schedule background operations based on virtual machine -operations. Instead, it is recommended that a callback be scheduled relatively -frequently (say every 1000 instructions) and external timer routines used to -determine whether or not background jobs need to be run. -

- - -

4.0 Adding New SQL Functions

- -

Beginning with version 2.4.0, SQLite allows the SQL language to be -extended with new functions implemented as C code. The following interface -is used: -

- -
-typedef struct sqlite_func sqlite_func;
-
-int sqlite_create_function(
-  sqlite *db,
-  const char *zName,
-  int nArg,
-  void (*xFunc)(sqlite_func*,int,const char**),
-  void *pUserData
-);
-int sqlite_create_aggregate(
-  sqlite *db,
-  const char *zName,
-  int nArg,
-  void (*xStep)(sqlite_func*,int,const char**),
-  void (*xFinalize)(sqlite_func*),
-  void *pUserData
-);
-
-char *sqlite_set_result_string(sqlite_func*,const char*,int);
-void sqlite_set_result_int(sqlite_func*,int);
-void sqlite_set_result_double(sqlite_func*,double);
-void sqlite_set_result_error(sqlite_func*,const char*,int);
-
-void *sqlite_user_data(sqlite_func*);
-void *sqlite_aggregate_context(sqlite_func*, int nBytes);
-int sqlite_aggregate_count(sqlite_func*);
-
- -

-The sqlite_create_function() interface is used to create -regular functions and sqlite_create_aggregate() is used to -create new aggregate functions. In both cases, the db -parameter is an open SQLite database on which the functions should -be registered, zName is the name of the new function, -nArg is the number of arguments, and pUserData is -a pointer which is passed through unchanged to the C implementation -of the function. Both routines return 0 on success and non-zero -if there are any errors. -

- -

-The length of a function name may not exceed 255 characters. -Any attempt to create a function whose name exceeds 255 characters -in length will result in an error. -

- -

-For regular functions, the xFunc callback is invoked once -for each function call. The implementation of xFunc should call -one of the sqlite_set_result_... interfaces to return its -result. The sqlite_user_data() routine can be used to -retrieve the pUserData pointer that was passed in when the -function was registered. -

- -

-For aggregate functions, the xStep callback is invoked once -for each row in the result and then xFinalize is invoked at the -end to compute a final answer. The xStep routine can use the -sqlite_aggregate_context() interface to allocate memory that -will be unique to that particular instance of the SQL function. -This memory will be automatically deleted after xFinalize is called. -The sqlite_aggregate_count() routine can be used to find out -how many rows of data were passed to the aggregate. The xFinalize -callback should invoke one of the sqlite_set_result_... -interfaces to set the final result of the aggregate. -

- -

-SQLite now implements all of its built-in functions using this -interface. For additional information and examples on how to create -new SQL functions, review the SQLite source code in the file -func.c. -

- -

5.0 Multi-Threading And SQLite

- -

-If SQLite is compiled with the THREADSAFE preprocessor macro set to 1, -then it is safe to use SQLite from two or more threads of the same process -at the same time. But each thread should have its own sqlite* -pointer returned from sqlite_open. It is never safe for two -or more threads to access the same sqlite* pointer at the same time. -

- -

-In precompiled SQLite libraries available on the website, the Unix -versions are compiled with THREADSAFE turned off but the windows -versions are compiled with THREADSAFE turned on. If you need something -different that this you will have to recompile. -

- -

-Under Unix, an sqlite* pointer should not be carried across a -fork() system call into the child process. The child process -should open its own copy of the database after the fork(). -

- -

6.0 Usage Examples

- -

For examples of how the SQLite C/C++ interface can be used, -refer to the source code for the sqlite program in the -file src/shell.c of the source tree. -Additional information about sqlite is available at -sqlite.html. -See also the sources to the Tcl interface for SQLite in -the source file src/tclsqlite.c.

-} -footer $rcsid diff --git a/sqlite/www/capi3.tcl b/sqlite/www/capi3.tcl deleted file mode 100644 index 76019bb..0000000 --- a/sqlite/www/capi3.tcl +++ /dev/null @@ -1,453 +0,0 @@ -set rcsid {$Id: capi3.tcl,v 1.7 2005/01/03 01:33:00 drh Exp $} -source common.tcl -header {C/C++ Interface For SQLite Version 3} -puts { -

C/C++ Interface For SQLite Version 3

- -

1.0 Overview

- -

-SQLite version 3.0 is a new version of SQLite, derived from -the SQLite 2.8.13 code base, but with an incompatible file format -and API. -SQLite version 3.0 was created to answer demand for the following features: -

- -
    -
  • Support for UTF-16.
  • -
  • User-definable text collating sequences.
  • -
  • The ability to store BLOBs in indexed columns.
  • -
- -

-It was necessary to move to version 3.0 to implement these features because -each requires incompatible changes to the database file format. Other -incompatible changes, such as a cleanup of the API, were introduced at the -same time under the theory that it is best to get your incompatible changes -out of the way all at once. -

- -

-The API for version 3.0 is similar to the version 2.X API, -but with some important changes. Most noticeably, the "sqlite_" -prefix that occurs on the beginning of all API functions and data -structures are changed to "sqlite3_". -This avoids confusion between the two APIs and allows linking against both -SQLite 2.X and SQLite 3.0 at the same time. -

- -

-There is no agreement on what the C datatype for a UTF-16 -string should be. Therefore, SQLite uses a generic type of void* -to refer to UTF-16 strings. Client software can cast the void* -to whatever datatype is appropriate for their system. -

- -

2.0 C/C++ Interface

- -

-The API for SQLite 3.0 includes 83 separate functions in addition -to several data structures and #defines. (A complete -API reference is provided as a separate document.) -Fortunately, the interface is not nearly as complex as its size implies. -Simple programs can still make do with only 3 functions: -sqlite3_open(), -sqlite3_exec(), and -sqlite3_close(). -More control over the execution of the database engine is provided -using -sqlite3_prepare() -to compile an SQLite statement into byte code and -sqlite3_step() -to execute that bytecode. -A family of routines with names beginning with -sqlite3_column_ -is used to extract information about the result set of a query. -Many interface functions come in pairs, with both a UTF-8 and -UTF-16 version. And there is a collection of routines -used to implement user-defined SQL functions and user-defined -text collating sequences. -

- - -

2.1 Opening and closing a database

- -
-   typedef struct sqlite3 sqlite3;
-   int sqlite3_open(const char*, sqlite3**);
-   int sqlite3_open16(const void*, sqlite3**);
-   int sqlite3_close(sqlite3*);
-   const char *sqlite3_errmsg(sqlite3*);
-   const void *sqlite3_errmsg16(sqlite3*);
-   int sqlite3_errcode(sqlite3*);
-
- -

-The sqlite3_open() routine returns an integer error code rather than -a pointer to the sqlite3 structure as the version 2 interface did. -The difference between sqlite3_open() -and sqlite3_open16() is that sqlite3_open16() takes UTF-16 (in host native -byte order) for the name of the database file. If a new database file -needs to be created, then sqlite3_open16() sets the internal text -representation to UTF-16 whereas sqlite3_open() sets the text -representation to UTF-8. -

- -

-The opening and/or creating of the database file is deferred until the -file is actually needed. This allows options and parameters, such -as the native text representation and default page size, to be -set using PRAGMA statements. -

- -

-The sqlite3_errcode() routine returns a result code for the most -recent major API call. sqlite3_errmsg() returns an English-language -text error message for the most recent error. The error message is -represented in UTF-8 and will be ephemeral - it could disappear on -the next call to any SQLite API function. sqlite3_errmsg16() works like -sqlite3_errmsg() except that it returns the error message represented -as UTF-16 in host native byte order. -

- -

-The error codes for SQLite version 3 are unchanged from version 2. -They are as follows: -

- -
-#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 sqlite_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   /* (Internal Only) Database table 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_ROW         100  /* sqlite_step() has another row ready */
-#define SQLITE_DONE        101  /* sqlite_step() has finished executing */
-
- -

2.2 Executing SQL statements

- -
-   typedef int (*sqlite_callback)(void*,int,char**, char**);
-   int sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void*, char**);
-
- -

-The sqlite3_exec function works much as it did in SQLite version 2. -Zero or more SQL statements specified in the second parameter are compiled -and executed. Query results are returned to a callback routine. -See the API reference for additional -information. -

- -

-In SQLite version 3, the sqlite3_exec routine is just a wrapper around -calls to the prepared statement interface. -

- -
-   typedef struct sqlite3_stmt sqlite3_stmt;
-   int sqlite3_prepare(sqlite3*, const char*, int, sqlite3_stmt**, const char**);
-   int sqlite3_prepare16(sqlite3*, const void*, int, sqlite3_stmt**, const void**);
-   int sqlite3_finalize(sqlite3_stmt*);
-   int sqlite3_reset(sqlite3_stmt*);
-
- -

-The sqlite3_prepare interface compiles a single SQL statement into byte code -for later execution. This interface is now the preferred way of accessing -the database. -

- -

-The SQL statement is a UTF-8 string for sqlite3_prepare(). -The sqlite3_prepare16() works the same way except -that it expects a UTF-16 string as SQL input. -Only the first SQL statement in the input string is compiled. -The fourth parameter is filled in with a pointer to the next (uncompiled) -SQLite statement in the input string, if any. -The sqlite3_finalize() routine deallocates a prepared SQL statement. -All prepared statements must be finalized before the database can be -closed. -The sqlite3_reset() routine resets a prepared SQL statement so that it -can be executed again. -

- -

-The SQL statement may contain tokens of the form "?" or "?nnn" or ":nnn:" -where "nnn" is an integer. Such tokens represent unspecified literal values -(or wildcards) to be filled in later by the -sqlite3_bind interface. -Each wildcard as an associated number given -by the "nnn" that follows the "?". If the "?" is not followed by an -integer, then its number one more than the number of prior wildcards -in the same SQL statement. It is allowed for the same wildcard -to occur more than once in the same SQL statement, in which case -all instance of that wildcard will be filled in with the same value. -Unbound wildcards have a value of 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, long long int);
-   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 n, void(*)(void*));
-   int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-
- -

-There is an assortment of sqlite3_bind routines used to assign values -to wildcards in a prepared SQL statement. Unbound wildcards -are interpreted as NULLs. Bindings are not reset by sqlite3_reset(). -But wildcards can be rebound to new values after an sqlite3_reset(). -

- -

-After an SQL statement has been prepared (and optionally bound), it -is executed using: -

- -
-   int sqlite3_step(sqlite3_stmt*);
-
- -

-The sqlite3_step() routine return SQLITE_ROW if it is returning a single -row of the result set, or SQLITE_DONE if execution has completed, either -normally or due to an error. It might also return SQLITE_BUSY if it is -unable to open the database file. If the return value is SQLITE_ROW, then -the following routines can be used to extract information about that row -of the result set: -

- -
-   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);
-   int sqlite3_column_count(sqlite3_stmt*);
-   const char *sqlite3_column_decltype(sqlite3_stmt *, int iCol);
-   const void *sqlite3_column_decltype16(sqlite3_stmt *, int iCol);
-   double sqlite3_column_double(sqlite3_stmt*, int iCol);
-   int sqlite3_column_int(sqlite3_stmt*, int iCol);
-   long long int sqlite3_column_int64(sqlite3_stmt*, int iCol);
-   const char *sqlite3_column_name(sqlite3_stmt*, int iCol);
-   const void *sqlite3_column_name16(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_column_count() -function returns the number of columns in -the results set. sqlite3_column_count() can be called at any time after -sqlite3_prepare(). -sqlite3_data_count() -works similarly to -sqlite3_column_count() except that it only works following sqlite3_step(). -If the previous call to sqlite3_step() returned SQLITE_DONE or an error code, -then sqlite3_data_count() will return 0 whereas sqlite3_column_count() will -continue to return the number of columns in the result set. -

- -

-The sqlite3_column_type() function returns the -datatype for the value in the Nth column. The return value is one -of these: -

- -
-   #define SQLITE_INTEGER  1
-   #define SQLITE_FLOAT    2
-   #define SQLITE_TEXT     3
-   #define SQLITE_BLOB     4
-   #define SQLITE_NULL     5
-
- -

-The sqlite3_column_decltype() routine returns text which is the -declared type of the column in the CREATE TABLE statement. For an -expression, the return type is an empty string. sqlite3_column_name() -returns the name of the Nth column. sqlite3_column_bytes() returns -the number of bytes in a column that has type BLOB or the number of bytes -in a TEXT string with UTF-8 encoding. sqlite3_column_bytes16() returns -the same value for BLOBs but for TEXT strings returns the number of bytes -in a UTF-16 encoding. -sqlite3_column_blob() return BLOB data. -sqlite3_column_text() return TEXT data as UTF-8. -sqlite3_column_text16() return TEXT data as UTF-16. -sqlite3_column_int() return INTEGER data in the host machines native -integer format. -sqlite3_column_int64() returns 64-bit INTEGER data. -Finally, sqlite3_column_double() return floating point data. -

- -

-It is not necessary to retrieve data in the format specify by -sqlite3_column_type(). If a different format is requested, the data -is converted automatically. -

- -

2.3 User-defined functions

- -

-User defined functions can be created using the following routine: -

- -
-   typedef struct sqlite3_value sqlite3_value;
-   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*)
-   );
-   #define SQLITE_UTF8     1
-   #define SQLITE_UTF16    2
-   #define SQLITE_UTF16BE  3
-   #define SQLITE_UTF16LE  4
-   #define SQLITE_ANY      5
-
- -

-The nArg parameter specifies the number of arguments to the function. -A value of 0 indicates that any number of arguments is allowed. The -eTextRep parameter specifies what representation text values are expected -to be in for arguments to this function. The value of this parameter should -be one of the parameters defined above. SQLite version 3 allows multiple -implementations of the same function using different text representations. -The database engine chooses the function that minimization the number -of text conversions required. -

- -

-Normal functions specify only xFunc and leave xStep and xFinal set to NULL. -Aggregate functions specify xStep and xFinal and leave xFunc set to NULL. -There is no separate sqlite3_create_aggregate() API. -

- -

-The function name is specified in UTF-8. A separate sqlite3_create_function16() -API works the same as sqlite_create_function() -except that the function name is specified in UTF-16 host byte order. -

- -

-Notice that the parameters to functions are now pointers to sqlite3_value -structures instead of pointers to strings as in SQLite version 2.X. -The following routines are used to extract useful information from these -"values": -

- -
-   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*);
-   long long int sqlite3_value_int64(sqlite3_value*);
-   const unsigned char *sqlite3_value_text(sqlite3_value*);
-   const void *sqlite3_value_text16(sqlite3_value*);
-   int sqlite3_value_type(sqlite3_value*);
-
- -

-Function implementations use the following APIs to acquire context and -to report results: -

- -
-   void *sqlite3_aggregate_context(sqlite3_context*, int nbyte);
-   void *sqlite3_user_data(sqlite3_context*);
-   void sqlite3_result_blob(sqlite3_context*, const void*, int n, 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*, long long int);
-   void sqlite3_result_null(sqlite3_context*);
-   void sqlite3_result_text(sqlite3_context*, const char*, int n, void(*)(void*));
-   void sqlite3_result_text16(sqlite3_context*, const void*, int n, void(*)(void*));
-   void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-   void *sqlite3_get_auxdata(sqlite3_context*, int);
-   void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));
-
- -

2.4 User-defined collating sequences

- -

-The following routines are used to implement user-defined -collating sequences: -

- -
-   sqlite3_create_collation(sqlite3*, const char *zName, int eTextRep, void*,
-      int(*xCompare)(void*,int,const void*,int,const void*));
-   sqlite3_create_collation16(sqlite3*, const void *zName, int eTextRep, void*,
-      int(*xCompare)(void*,int,const void*,int,const void*));
-   sqlite3_collation_needed(sqlite3*, void*, 
-      void(*)(void*,sqlite3*,int eTextRep,const char*));
-   sqlite3_collation_needed16(sqlite3*, void*,
-      void(*)(void*,sqlite3*,int eTextRep,const void*));
-
- -

-The sqlite3_create_collation() function specifies a collating sequence name -and a comparison function to implement that collating sequence. The -comparison function is only used for comparing text values. The eTextRep -parameter is one of SQLITE_UTF8, SQLITE_UTF16LE, SQLITE_UTF16BE, or -SQLITE_ANY to specify which text representation the comparison function works -with. Separate comparison functions can exist for the same collating -sequence for each of the UTF-8, UTF-16LE and UTF-16BE text representations. -The sqlite3_create_collation16() works like sqlite3_create_collation() except -that the collation name is specified in UTF-16 host byte order instead of -in UTF-8. -

- -

-The sqlite3_collation_needed() routine registers a callback which the -database engine will invoke if it encounters an unknown collating sequence. -The callback can lookup an appropriate comparison function and invoke -sqlite_3_create_collation() as needed. The fourth parameter to the callback -is the name of the collating sequence in UTF-8. For sqlite3_collation_need16() -the callback sends the collating sequence name in UTF-16 host byte order. -

-} -footer $rcsid diff --git a/sqlite/www/capi3ref.tcl b/sqlite/www/capi3ref.tcl deleted file mode 100644 index fa69b1b..0000000 --- a/sqlite/www/capi3ref.tcl +++ /dev/null @@ -1,1137 +0,0 @@ -set rcsid {$Id: capi3ref.tcl,v 1.17 2004/12/07 02:14:52 drh Exp $} -source common.tcl -header {C/C++ Interface For SQLite Version 3} -puts { -

C/C++ Interface For SQLite Version 3

-} - -proc api {name prototype desc {notused x}} { - global apilist - if {$name==""} { - regsub -all {sqlite3_[a-z0-9_]+\(} $prototype \ - {[lappend name [string trimright & (]]} x1 - subst $x1 - } - lappend apilist [list $name $prototype $desc] -} - -api {result-codes} { -#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 sqlite_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 /* (Internal Only) Database table 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 constraint 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_ROW 100 /* sqlite_step() has another row ready */ -#define SQLITE_DONE 101 /* sqlite_step() has finished executing */ -} { -Many SQLite functions return an integer result code from the set shown -above in order to indicates success or failure. -} - -api {} { - const char *sqlite3_libversion(void); -} { - Return a pointer to a string which contains the version number of - the library. The same string is available in the global - variable named "sqlite3_version". This interface is provided since - windows is unable to access global variables in DLLs. -} - -api {} { - void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); -} { - Aggregate functions use this 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. -} - -api {} { - int sqlite3_aggregate_count(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. -} - -api {} { - 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, long long int); - 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 n, void(*)(void*)); - #define SQLITE_STATIC ((void(*)(void *))0) - #define SQLITE_TRANSIENT ((void(*)(void *))-1) -} { - In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(), - one or more literals can be replace by a parameter "?" or ":AAA" or "\$VVV" - where AAA is an alphanumeric identifier and VVV is a variable name according - to the syntax rules of the TCL programming language. - The values of these parameters (also called "host parameter names") - can be set using the sqlite3_bind_*() routines. - - The first argument to the sqlite3_bind_*() routines always is a pointer - to the sqlite3_stmt structure returned from sqlite3_prepare(). The second - argument is the index of the parameter to be set. The first parameter has - an index of 1. When the same named parameter is used more than once, second - and subsequent - occurrences have the same index as the first occurrence. The index for - named parameters can be looked up using the - sqlite3_bind_parameter_name() API if desired. - - The fifth argument 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 before returning. - - The sqlite3_bind_*() routines must be called after - sqlite3_prepare() or sqlite3_reset() and before sqlite3_step(). - Bindings are not cleared by the sqlite3_reset() routine. - Unbound parameters are interpreted as NULL. -} - -api {} { - int sqlite3_bind_parameter_count(sqlite3_stmt*); -} { - Return the number of parameters in the precompiled statement given as - the argument. -} - -api {} { - const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int n); -} { - Return the name of the n-th parameter in the precompiled statement. - Parameters of the form ":AAA" or "\$VVV" have a name which is the - string ":AAA" or "\$VVV". In other words, the initial ":" or "$" - is included as part of the name. - Parameters of the form "?" have no name. - - If the value n is out of range or if the n-th parameter is nameless, - then NULL is returned. The returned string is always in the - UTF-8 encoding. -} - -api {} { - int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); -} { - Return the index of the parameter with the given name. - The name must match exactly. - If there is no parameter with the given name, return 0. - The string zName is always in the UTF-8 encoding. -} - -api {} { - int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); -} { - 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 two arguments. The - second argument is the number of prior calls to the busy callback - for the same lock. 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. -} - -api {} { - int sqlite3_busy_timeout(sqlite3*, int ms); -} { - 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" milliseconds of sleeping have been done. After - "ms" milliseconds 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. -} - -api {} { - int sqlite3_changes(sqlite3*); -} { - This function returns the number of database rows that were changed - (or inserted or deleted) by the most recently completed - INSERT, UPDATE, or DELETE - statement. Only changes that are directly specified by the INSERT, - UPDATE, or DELETE statement are counted. Auxiliary changes caused by - triggers are not counted. Use the sqlite3_total_changes() function - to find the total number of changes including changes caused by triggers. - - Within the body of a trigger, the sqlite3_changes() function does work - to report the number of rows that were changed for the most recently - completed INSERT, UPDATE, or DELETE statement within the trigger body. - - 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 from 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. -} - -api {} { - int sqlite3_total_changes(sqlite3*); -} { - This function returns the total number of database rows that have - be modified, inserted, or deleted since the database connection was - created using sqlite3_open(). All changes are counted, including - changes by triggers and changes to TEMP and auxiliary databases. - Except, changes to the SQLITE_MASTER table (caused by statements - such as CREATE TABLE) are not counted. Nor are changes counted when - an entire table is deleted using DROP TABLE. - - See also the sqlite3_changes() API. - - 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. -} - -api {} { - int sqlite3_close(sqlite3*); -} { - Call this function with a pointer to a structure that was previously - returned from sqlite3_open() or sqlite3_open16() - and the corresponding database will by closed. - - SQLITE_OK is returned if the close is successful. If there are - prepared statements that have not been finalized, then SQLITE_BUSY - is returned. SQLITE_ERROR might be returned if the argument is not - a valid connection pointer returned by sqlite3_open() or if the connection - pointer has been closed previously. -} - -api {} { -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); -long long int 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); -#define SQLITE_INTEGER 1 -#define SQLITE_FLOAT 2 -#define SQLITE_TEXT 3 -#define SQLITE_BLOB 4 -#define SQLITE_NULL 5 -} { - These routines return information about the information - in a single column of the current result row of a query. In every - case the first argument 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 column index is out of range, the result is undefined. - - If the result is a BLOB then the sqlite3_column_bytes() routine returns - the number of bytes in that BLOB. No type conversions occur. - If the result is a string (or a number since a number can be converted - into a string) then sqlite3_column_bytes() converts - the value into a UTF-8 string and returns - the number of bytes in the resulting string. The value returned does - not include the \\000 terminator at the end of the string. The - sqlite3_column_bytes16() routine converts the value into a UTF-16 - encoding and returns the number of bytes (not characters) in the - resulting string. The \\u0000 terminator is not included in this count. - - 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 TypeRequested TypeConversion
NULL INTEGERResult 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 INTEGERConvert from float to integer
FLOAT TEXT ASCII rendering of the float
FLOAT BLOB Same as FLOAT->TEXT
TEXT INTEGERUse atoi()
TEXT FLOAT Use atof()
TEXT BLOB No change
BLOB INTEGERConvert to TEXT then use atoi()
BLOB FLOAT Convert to TEXT then use atof()
BLOB TEXT Add a \\000 terminator if needed
- -} - -api {} { -int sqlite3_column_count(sqlite3_stmt *pStmt); -} { - Return the number of columns in the result set returned by the prepared - SQL statement. This routine returns 0 if pStmt is an SQL statement - that does not return data (for example an UPDATE). - - See also sqlite3_data_count(). -} - -api {} { -const char *sqlite3_column_decltype(sqlite3_stmt *, int i); -const void *sqlite3_column_decltype16(sqlite3_stmt*,int); -} { - The first argument is a prepared 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 - UTF-8 encoded for sqlite3_column_decltype() and UTF-16 encoded - for sqlite3_column_decltype16(). - 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). -} - -api {} { -const char *sqlite3_column_name(sqlite3_stmt*,int); -const void *sqlite3_column_name16(sqlite3_stmt*,int); -} { - The first argument is a prepared SQL statement. This function returns - the column heading for the Nth column of that statement, where N is the - second function argument. The string returned is UTF-8 for - sqlite3_column_name() and UTF-16 for sqlite3_column_name16(). -} - -api {} { -void *sqlite3_commit_hook(sqlite3*, int(*xCallback)(void*), void *pArg); -} { - Experimental - - 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. Only a single commit - hook callback can be registered at a time. -} - -api {} { -int sqlite3_complete(const char *sql); -int sqlite3_complete16(const void *sql); -} { - These functions return true if the given input string comprises - one or more complete SQL statements. - The argument must be a nul-terminated UTF-8 string for sqlite3_complete() - and a nul-terminated UTF-16 string for sqlite3_complete16(). -} {} - -api {} { -int sqlite3_create_collation( - sqlite3*, - const char *zName, - int pref16, - void*, - int(*xCompare)(void*,int,const void*,int,const void*) -); -int sqlite3_create_collation16( - sqlite3*, - const char *zName, - int pref16, - void*, - int(*xCompare)(void*,int,const void*,int,const void*) -); -#define SQLITE_UTF8 1 -#define SQLITE_UTF16BE 2 -#define SQLITE_UTF16LE 3 -#define SQLITE_UTF16 4 -} { - 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. The - SQLITE_UTF16 constant indicates that text strings are expected in - UTF-16 in the native byte order of the host machine. - - 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 argument. - - 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). -} - -api {} { -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*) -); -} { - 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 argument 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. -} - -api {} { -int sqlite3_create_function( - sqlite3 *, - const char *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 sqlite3_create_function16( - sqlite3*, - 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*) -); -#define SQLITE_UTF8 1 -#define SQLITE_UTF16 2 -#define SQLITE_UTF16BE 3 -#define SQLITE_UTF16LE 4 -#define SQLITE_ANY 5 -} { - These two functions are used to add SQL functions or aggregates - implemented in C. The - only difference between these two routines is that the second argument, 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 argument is the number of arguments that the function or - aggregate takes. If this argument is -1 then the function or - aggregate may take any number of arguments. - - The fourth argument, eTextRep, specifies what type of text arguments - this function prefers to receive. Any function should be able to work - work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be - more efficient with one representation than another. Users are allowed - to specify separate implementations for the same function which are called - depending on the text representation of the arguments. The the implementation - which provides the best match is used. If there is only a single - implementation which does not care what text representation is used, - then the fourth argument should be SQLITE_ANY. - - The fifth argument is an arbitrary pointer. The function implementations - can gain access to this pointer using the sqlite_user_data() API. - - The sixth, seventh and eighth argumens, 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 arguments. An aggregate function requires an implementation - of xStep and xFinal, and NULL should be passed for xFunc. To delete an - existing user function or aggregate, pass NULL for all three function - callbacks. Specifying an inconstant set of callback values, such as an - xFunc and an xFinal, or an xStep but no xFinal, results in an SQLITE_ERROR - return. -} - -api {} { -int sqlite3_data_count(sqlite3_stmt *pStmt); -} { - 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 - prepared SQL statement, this routine returns zero. -} - -api {} { -int sqlite3_errcode(sqlite3 *db); -} { - Return the error code for the most recent failed sqlite3_* API call associated - with sqlite3 handle 'db'. If a prior API call failed but the most recent - API call succeeded, the return value from this routine is undefined. - - 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. Calls to API routines that do not return - an error code (examples: sqlite3_data_count() or sqlite3_mprintf()) do - not change the error code returned by this routine. - - 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(). -} {} - -api {} { -const char *sqlite3_errmsg(sqlite3*); -const void *sqlite3_errmsg16(sqlite3*); -} { - Return a pointer to a UTF-8 encoded string (sqlite3_errmsg) - or a UTF-16 encoded string (sqlite3_errmsg16) 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. -} - -api {} { -int sqlite3_exec( - sqlite3*, /* An open database */ - const char *sql, /* SQL to be executed */ - sqlite_callback, /* Callback function */ - void *, /* 1st argument to callback function */ - char **errmsg /* Error msg written here */ -); -} { - 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 argument 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 argument is an arbitrary pointer that is passed - to the callback function as its first argument. - - The 2nd argument to the callback function is the number of - columns in the query result. The 3rd argument to the callback - is an array of strings holding the values for each column. - The 4th argument 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.) -} {} - -api {} { -int sqlite3_finalize(sqlite3_stmt *pStmt); -} { - The sqlite3_finalize() function is called to delete a prepared - 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. - - All prepared statements must finalized before sqlite3_close() is - called or else the close will fail with a return code of SQLITE_BUSY. - - 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 canceled, depending on the circumstances, - and the result code returned will be SQLITE_ABORT. -} - -api {} { -void sqlite3_free(char *z); -} { - Use this routine to free memory obtained from - sqlite3_mprintf() or sqlite3_vmprintf(). -} - -api {} { -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 */ -); -void sqlite3_free_table(char **result); -} { - 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 - malloc() 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(). -} - -api {sqlite3_interrupt} { - void sqlite3_interrupt(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. -} {} - -api {} { -long long int sqlite3_last_insert_rowid(sqlite3*); -} { - 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.) This 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. -} {} - -api {} { -char *sqlite3_mprintf(const char*,...); -char *sqlite3_vmprintf(const char*, va_list); -} { - These 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 possibility 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!";
- 
- - One 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. -} {} - -api {} { -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 */ -); -} { - 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 will be created - as needed. - The encoding for the database will be 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. -} - -api {} { -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 */ -); -} { - 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 argument "db" is an SQLite database handle. The second - argument "zSql" is the statement to be compiled, encoded as either - UTF-8 or UTF-16 (see above). If the next argument, "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. The calling - procedure is responsible for deleting this compiled SQL statement - using sqlite3_finalize() after it has finished with it. - - On success, SQLITE_OK is returned. Otherwise an error code is returned. -} - -api {} { -void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); -} { - Experimental - - 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. - -} - -api {} { -int sqlite3_reset(sqlite3_stmt *pStmt); -} { - The sqlite3_reset() function is called to reset a prepared 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. -} - -api {} { -void sqlite3_result_blob(sqlite3_context*, const void*, int n, 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*, long long int); -void sqlite3_result_null(sqlite3_context*); -void sqlite3_result_text(sqlite3_context*, const char*, int n, void(*)(void*)); -void sqlite3_result_text16(sqlite3_context*, const void*, int n, void(*)(void*)); -void sqlite3_result_text16be(sqlite3_context*, const void*, int n, void(*)(void*)); -void sqlite3_result_text16le(sqlite3_context*, const void*, int n, void(*)(void*)); -void sqlite3_result_value(sqlite3_context*, sqlite3_value*); -} { - User-defined functions invoke these routines in order to - set their return value. The sqlite3_result_value() routine is used - to return an exact copy of one of the arguments to the function. - - The operation of these routines is very similar to the operation of - sqlite3_bind_blob() and its cousins. Refer to the documentation there - for additional information. -} - -api {} { -int sqlite3_set_authorizer( - sqlite3*, - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), - void *pUserData -); -#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_DENY 1 /* Abort the SQL statement with an error */ -#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ -} { - 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 should - return 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. - - The second argument to the access authorization function will be one - of the defined constants shown. These values signify what kind of operation - is to be authorized. The 3rd and 4th arguments to the authorization - function will be arguments or NULL depending on which of the following - codes is used as the second argument. The 5th argument is the name - of the database ("main", "temp", etc.) if applicable. The 6th argument - 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. - - The return value of the authorization function should be one of the - constants SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. - - The intent of this routine is to allow applications to safely execute - user-entered SQL. An appropriate callback can deny the user-entered - SQL access certain operations (ex: anything that changes the database) - or to deny access to certain tables or columns within the database. -} - -api {} { -int sqlite3_step(sqlite3_stmt*); -} { - After an SQL query has been prepared 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 without first calling sqlite3_reset() to reset the virtual - machine back to its initial state. - - 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. 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 simultaneously by two or more threads. -} - -api {} { -void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); -} { - Register a function that is called each time an SQL statement is evaluated. - The callback function is invoked on the first call to sqlite3_step() after - calls to sqlite3_prepare() or sqlite3_reset(). - This function can be used (for example) to generate - a log file of all SQL executed against a database. This can be - useful when debugging an application that uses SQLite. -} - -api {} { -void *sqlite3_user_data(sqlite3_context*); -} { - The pUserData argument to the sqlite3_create_function() and - sqlite3_create_function16() routines used to register user functions - is available to the implementation of the function using this - call. -} - -api {} { -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*); -long long int sqlite3_value_int64(sqlite3_value*); -const unsigned char *sqlite3_value_text(sqlite3_value*); -const void *sqlite3_value_text16(sqlite3_value*); -const void *sqlite3_value_text16be(sqlite3_value*); -const void *sqlite3_value_text16le(sqlite3_value*); -int sqlite3_value_type(sqlite3_value*); -} { - This group of routines returns information about arguments to - a user-defined function. Function implementations use these routines - to access their arguments. 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. - - See the documentation under sqlite3_column_blob for additional - information. -} - -set n 0 -set i 0 -foreach item $apilist { - set namelist [lindex $item 0] - foreach name $namelist { - set n_to_name($n) $name - set n_to_idx($n) $i - set name_to_idx($name) $i - incr n - } - incr i -} -set i 0 -foreach name [lsort [array names name_to_idx]] { - set sname($i) $name - incr i -} -puts {} -set nrow [expr {($n+2)/3}] -set i 0 -for {set j 0} {$j<3} {incr j} { - if {$j>0} {puts {}} - puts {} -} -puts "
} - set limit [expr {$i+$nrow}] - puts {
    } - while {$i<$limit && $i<$n} { - set name $sname($i) - if {[regexp {^sqlite} $name]} {set display $name} {set display $name} - puts "
  • $display
  • " - incr i - } - puts {
" -puts "" - -proc resolve_name {ignore_list name} { - global name_to_idx - if {![info exists name_to_idx($name)] || [lsearch $ignore_list $name]>=0} { - return $name - } else { - return "$name" - } -} - -foreach name [lsort [array names name_to_idx]] { - set i $name_to_idx($name) - if {[info exists done($i)]} continue - set done($i) 1 - foreach {namelist prototype desc} [lindex $apilist $i] break - foreach name $namelist { - puts "" - } - puts "


" - puts "
"
-  regsub "^( *\n)+" $prototype {} p2
-  regsub "(\n *)+\$" $p2 {} p3
-  puts $p3
-  puts "
" - regsub -all {\[} $desc {\[} desc - regsub -all {sqlite3_[a-z0-9_]+} $desc "\[resolve_name $name &\]" d2 - regsub -all "\n( *\n)+" [subst $d2] "

\n\n

" d3 - puts "

$d3

" -} - -footer $rcsid diff --git a/sqlite/www/changes.tcl b/sqlite/www/changes.tcl deleted file mode 100644 index 348cd72..0000000 --- a/sqlite/www/changes.tcl +++ /dev/null @@ -1,1258 +0,0 @@ -# -# Run this script to generated a changes.html output file -# -source common.tcl -header {SQLite changes} -puts { -

-This page provides a high-level summary of changes to SQLite. -For more detail, refer the the checkin logs generated by -CVS at - -http://www.sqlite.org/cvstrac/timeline. -

- -
-} - - -proc chng {date desc} { - puts "
$date
" - puts "

    $desc

" -} - -chng {2005 February 15 (3.1.2)} { -
  • Fix a bug that can lead to database corruption if there are two -open connections to the same database and one connection does a VACUUM -and the second makes some change to the database.
  • -
  • Allow "?" parameters in the LIMIT clause.
  • -
  • Fix VACUUM so that it works with AUTOINCREMENT.
  • -
  • Fix a race condition in AUTOVACUUM that can lead to corrupt databases
  • -
  • Add a numeric version number to the sqlite3.h include file.
  • -
  • Other minor bug fixes and performance enhancements.
  • -} - -chng {2005 February 15 (2.8.16)} { -
  • Fix a bug that can lead to database corruption if there are two -open connections to the same database and one connection does a VACUUM -and the second makes some change to the database.
  • -
  • Correctly handle quoted names in CREATE INDEX statements.
  • -
  • Fix a naming conflict between sqlite.h and sqlite3.h.
  • -
  • Avoid excess heap usage when copying expressions.
  • -
  • Other minor bug fixes.
  • -} - -chng {2005 February 1 (3.1.1 BETA)} { -
  • Automatic caching of prepared statements in the TCL interface
  • -
  • ATTACH and DETACH as well as some other operations cause existing - prepared statements to expire.
  • -
  • Numerious minor bug fixes
  • -} - -chng {2005 January 21 (3.1.0 ALPHA)} { -
  • Autovacuum support added
  • -
  • CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP added
  • -
  • Support for the EXISTS clause added.
  • -
  • Support for correlated subqueries added.
  • -
  • Added the ESCAPE clause on the LIKE operator.
  • -
  • Support for ALTER TABLE ... RENAME TABLE ... added
  • -
  • AUTOINCREMENT keyword supported on INTEGER PRIMARY KEY
  • -
  • Many SQLITE_OMIT_ macros inserts to omit features at compile-time - and reduce the library footprint.
  • -
  • The REINDEX command was added.
  • -
  • The engine no longer consults the main table if it can get - all the information it needs from an index.
  • -
  • Many nuisance bugs fixed.
  • -} - -chng {2004 October 11 (3.0.8)} { -
  • Add support for DEFERRED, IMMEDIATE, and EXCLUSIVE transactions.
  • -
  • Allow new user-defined functions to be created when there are -already one or more precompiled SQL statements.
  • -
  • Fix portability problems for Mingw/MSYS.
  • -
  • Fix a byte alignment problem on 64-bit Sparc machines.
  • -
  • Fix the ".import" command of the shell so that it ignores \r -characters at the end of lines.
  • -
  • The "csv" mode option in the shell puts strings inside double-quotes.
  • -
  • Fix typos in documentation.
  • -
  • Convert array constants in the code to have type "const".
  • -
  • Numerous code optimizations, specially optimizations designed to -make the code footprint smaller.
  • -} - -chng {2004 September 18 (3.0.7)} { -
  • The BTree module allocates large buffers using malloc() instead of - off of the stack, in order to play better on machines with limited - stack space.
  • -
  • Fixed naming conflicts so that versions 2.8 and 3.0 can be - linked and used together in the same ANSI-C source file.
  • -
  • New interface: sqlite3_bind_parameter_index()
  • -
  • Add support for wildcard parameters of the form: "?nnn"
  • -
  • Fix problems found on 64-bit systems.
  • -
  • Removed encode.c file (containing unused routines) from the - version 3.0 source tree.
  • -
  • The sqlite3_trace() callbacks occur before each statement - is executed, not when the statement is compiled.
  • -
  • Makefile updates and miscellaneous bug fixes.
  • -} - -chng {2004 September 02 (3.0.6 beta)} { -
  • Better detection and handling of corrupt database files.
  • -
  • The sqlite3_step() interface returns SQLITE_BUSY if it is unable - to commit a change because of a lock
  • -
  • Combine the implementations of LIKE and GLOB into a single - pattern-matching subroutine.
  • -
  • Miscellaneous code size optimizations and bug fixes
  • -} - -chng {2004 August 29 (3.0.5 beta)} { -
  • Support for ":AAA" style bind parameter names.
  • -
  • Added the new sqlite3_bind_parameter_name() interface.
  • -
  • Support for TCL variable names embedded in SQL statements in the - TCL bindings.
  • -
  • The TCL bindings transfer data without necessarily doing a conversion - to a string.
  • -
  • The database for TEMP tables is not created until it is needed.
  • -
  • Add the ability to specify an alternative temporary file directory - using the "sqlite_temp_directory" global variable.
  • -
  • A compile-time option (SQLITE_BUSY_RESERVED_LOCK) causes the busy - handler to be called when there is contention for a RESERVED lock.
  • -
  • Various bug fixes and optimizations
  • -} - -chng {2004 August 8 (3.0.4 beta)} { -
  • CREATE TABLE and DROP TABLE now work correctly as prepared statements.
  • -
  • Fix a bug in VACUUM and UNIQUE indices.
  • -
  • Add the ".import" command to the command-line shell.
  • -
  • Fix a bug that could cause index corruption when an attempt to - delete rows of a table is blocked by a pending query.
  • -
  • Library size optimizations.
  • -
  • Other minor bug fixes.
  • -} - -chng {2004 July 22 (2.8.15)} { -
  • This is a maintenance release only. Various minor bugs have been -fixed and some portability enhancements are added.
  • -} - -chng {2004 July 22 (3.0.3 beta)} { -
  • The second beta release for SQLite 3.0.
  • -
  • Add support for "PRAGMA page_size" to adjust the page size of -the database.
  • -
  • Various bug fixes and documentation updates.
  • -} - -chng {2004 June 30 (3.0.2 beta)} { -
  • The first beta release for SQLite 3.0.
  • -} - -chng {2004 June 22 (3.0.1 alpha)} { -
  • - *** Alpha Release - Research And Testing Use Only *** -
  • Lots of bug fixes.
  • -} - -chng {2004 June 18 (3.0.0 alpha)} { -
  • - *** Alpha Release - Research And Testing Use Only *** -
  • Support for internationalization including UTF-8, UTF-16, and - user defined collating sequences.
  • -
  • New file format that is 25% to 35% smaller for typical use.
  • -
  • Improved concurrency.
  • -
  • Atomic commits for ATTACHed databases.
  • -
  • Remove cruft from the APIs.
  • -
  • BLOB support.
  • -
  • 64-bit rowids.
  • -
  • More information. -} - -chng {2004 June 9 (2.8.14)} { -
  • Fix the min() and max() optimizer so that it works when the FROM - clause consists of a subquery.
  • -
  • Ignore extra whitespace at the end of of "." commands in the shell.
  • -
  • Bundle sqlite_encode_binary() and sqlite_decode_binary() with the - library.
  • -
  • The TEMP_STORE and DEFAULT_TEMP_STORE pragmas now work.
  • -
  • Code changes to compile cleanly using OpenWatcom.
  • -
  • Fix VDBE stack overflow problems with INSTEAD OF triggers and - NULLs in IN operators.
  • -
  • Add the global variable sqlite_temp_directory which if set defines the - directory in which temporary files are stored.
  • -
  • sqlite_interrupt() plays well with VACUUM.
  • -
  • Other minor bug fixes.
  • -} - -chng {2004 March 8 (2.8.13)} { -
  • Refactor parts of the code in order to make the code footprint - smaller. The code is now also a little bit faster.
  • -
  • sqlite_exec() is now implemented as a wrapper around sqlite_compile() - and sqlite_step().
  • -
  • The built-in min() and max() functions now honor the difference between - NUMERIC and TEXT datatypes. Formerly, min() and max() always assumed - their arguments were of type NUMERIC.
  • -
  • New HH:MM:SS modifier to the built-in date/time functions.
  • -
  • Experimental sqlite_last_statement_changes() API added. Fixed the - the last_insert_rowid() function so that it works correctly with - triggers.
  • -
  • Add functions prototypes for the database encryption API.
  • -
  • Fix several nuisance bugs.
  • -} - -chng {2004 February 8 (2.8.12)} { -
  • Fix a bug that will might corrupt the rollback journal if a power failure - or external program halt occurs in the middle of a COMMIT. The corrupt - journal can lead to database corruption when it is rolled back.
  • -
  • Reduce the size and increase the speed of various modules, especially - the virtual machine.
  • -
  • Allow "<expr> IN <table>" as a shorthand for - "<expr> IN (SELECT * FROM <table>".
  • -
  • Optimizations to the sqlite_mprintf() routine.
  • -
  • Make sure the MIN() and MAX() optimizations work within subqueries.
  • -} - -chng {2004 January 14 (2.8.11)} { -
  • Fix a bug in how the IN operator handles NULLs in subqueries. The bug - was introduced by the previous release.
  • -} - -chng {2004 January 13 (2.8.10)} { -
  • Fix a potential database corruption problem on Unix caused by the fact - that all posix advisory locks are cleared whenever you close() a file. - The work around it to embargo all close() calls while locks are - outstanding.
  • -
  • Performance enhancements on some corner cases of COUNT(*).
  • -
  • Make sure the in-memory backend response sanely if malloc() fails.
  • -
  • Allow sqlite_exec() to be called from within user-defined SQL - functions.
  • -
  • Improved accuracy of floating-point conversions using "long double".
  • -
  • Bug fixes in the experimental date/time functions.
  • -} - -chng {2004 January 5 (2.8.9)} { -
  • Fix a 32-bit integer overflow problem that could result in corrupt - indices in a database if large negative numbers (less than -2147483648) - were inserted into a indexed numeric column.
  • -
  • Fix a locking problem on multi-threaded Linux implementations.
  • -
  • Always use "." instead of "," as the decimal point even if the locale - requests ",".
  • -
  • Added UTC to localtime conversions to the experimental date/time - functions.
  • -
  • Bug fixes to date/time functions.
  • -} - -chng {2003 December 17 (2.8.8)} { -
  • Fix a critical bug introduced into 2.8.0 which could cause - database corruption.
  • -
  • Fix a problem with 3-way joins that do not use indices
  • -
  • The VACUUM command now works with the non-callback API
  • -
  • Improvements to the "PRAGMA integrity_check" command
  • -} - -chng {2003 December 4 (2.8.7)} { -
  • Added experimental sqlite_bind() and sqlite_reset() APIs.
  • -
  • If the name of the database is an empty string, open a new database - in a temporary file that is automatically deleted when the database - is closed.
  • -
  • Performance enhancements in the lemon-generated parser
  • -
  • Experimental date/time functions revised.
  • -
  • Disallow temporary indices on permanent tables.
  • -
  • Documentation updates and typo fixes
  • -
  • Added experimental sqlite_progress_handler() callback API
  • -
  • Removed support for the Oracle8 outer join syntax.
  • -
  • Allow GLOB and LIKE operators to work as functions.
  • -
  • Other minor documentation and makefile changes and bug fixes.
  • -} - -chng {2003 August 21 (2.8.6)} { -
  • Moved the CVS repository to www.sqlite.org
  • -
  • Update the NULL-handling documentation.
  • -
  • Experimental date/time functions added.
  • -
  • Bug fix: correctly evaluate a view of a view without segfaulting.
  • -
  • Bug fix: prevent database corruption if you dropped a - trigger that had the same name as a table.
  • -
  • Bug fix: allow a VACUUM (without segfaulting) on an empty - database after setting the EMPTY_RESULT_CALLBACKS pragma.
  • -
  • Bug fix: if an integer value will not fit in a 32-bit int, store it in - a double instead.
  • -
  • Bug fix: Make sure the journal file directory entry is committed to disk - before writing the database file.
  • -} - -chng {2003 July 22 (2.8.5)} { -
  • Make LIMIT work on a compound SELECT statement.
  • -
  • LIMIT 0 now shows no rows. Use LIMIT -1 to see all rows.
  • -
  • Correctly handle comparisons between an INTEGER PRIMARY KEY and - a floating point number.
  • -
  • Fix several important bugs in the new ATTACH and DETACH commands.
  • -
  • Updated the NULL-handling document.
  • -
  • Allow NULL arguments in sqlite_compile() and sqlite_step().
  • -
  • Many minor bug fixes
  • -} - -chng {2003 June 29 (2.8.4)} { -
  • Enhanced the "PRAGMA integrity_check" command to verify indices.
  • -
  • Added authorization hooks for the new ATTACH and DETACH commands.
  • -
  • Many documentation updates
  • -
  • Many minor bug fixes
  • -} - -chng {2003 June 4 (2.8.3)} { -
  • Fix a problem that will corrupt the indices on a table if you - do an INSERT OR REPLACE or an UPDATE OR REPLACE on a table that - contains an INTEGER PRIMARY KEY plus one or more indices.
  • -
  • Fix a bug in windows locking code so that locks work correctly - when simultaneously accessed by Win95 and WinNT systems.
  • -
  • Add the ability for INSERT and UPDATE statements to refer to the - "rowid" (or "_rowid_" or "oid") columns.
  • -
  • Other important bug fixes
  • -} - -chng {2003 May 17 (2.8.2)} { -
  • Fix a problem that will corrupt the database file if you drop a - table from the main database that has a TEMP index.
  • -} - -chng {2003 May 16 (2.8.1)} { -
  • Reactivated the VACUUM command that reclaims unused disk space in - a database file.
  • -
  • Added the ATTACH and DETACH commands to allow interacting with multiple - database files at the same time.
  • -
  • Added support for TEMP triggers and indices.
  • -
  • Added support for in-memory databases.
  • -
  • Removed the experimental sqlite_open_aux_file(). Its function is - subsumed in the new ATTACH command.
  • -
  • The precedence order for ON CONFLICT clauses was changed so that - ON CONFLICT clauses on BEGIN statements have a higher precedence than - ON CONFLICT clauses on constraints. -
  • Many, many bug fixes and compatibility enhancements.
  • -} - -chng {2003 Feb 16 (2.8.0)} { -
  • Modified the journal file format to make it more resistant to corruption - that can occur after an OS crash or power failure.
  • -
  • Added a new C/C++ API that does not use callback for returning data.
  • -} - -chng {2003 Jan 25 (2.7.6)} { -
  • Performance improvements. The library is now much faster.
  • -
  • Added the sqlite_set_authorizer() API. Formal documentation has - not been written - see the source code comments for instructions on - how to use this function.
  • -
  • Fix a bug in the GLOB operator that was preventing it from working - with upper-case letters.
  • -
  • Various minor bug fixes.
  • -} - -chng {2002 Dec 27 (2.7.5)} { -
  • Fix an uninitialized variable in pager.c which could (with a probability - of about 1 in 4 billion) result in a corrupted database.
  • -} - -chng {2002 Dec 17 (2.7.4)} { -
  • Database files can now grow to be up to 2^41 bytes. The old limit - was 2^31 bytes.
  • -
  • The optimizer will now scan tables in the reverse if doing so will - satisfy an ORDER BY ... DESC clause.
  • -
  • The full pathname of the database file is now remembered even if - a relative path is passed into sqlite_open(). This allows - the library to continue operating correctly after a chdir().
  • -
  • Speed improvements in the VDBE.
  • -
  • Lots of little bug fixes.
  • -} - -chng {2002 Oct 30 (2.7.3)} { -
  • Various compiler compatibility fixes.
  • -
  • Fix a bug in the "expr IN ()" operator.
  • -
  • Accept column names in parentheses.
  • -
  • Fix a problem with string memory management in the VDBE
  • -
  • Fix a bug in the "table_info" pragma"
  • -
  • Export the sqlite_function_type() API function in the Windows DLL
  • -
  • Fix locking behavior under windows
  • -
  • Fix a bug in LEFT OUTER JOIN
  • -} - -chng {2002 Sep 25 (2.7.2)} { -
  • Prevent journal file overflows on huge transactions.
  • -
  • Fix a memory leak that occurred when sqlite_open() failed.
  • -
  • Honor the ORDER BY and LIMIT clause of a SELECT even if the - result set is used for an INSERT.
  • -
  • Do not put write locks on the file used to hold TEMP tables.
  • -
  • Added documentation on SELECT DISTINCT and on how SQLite handles NULLs.
  • -
  • Fix a problem that was causing poor performance when many thousands - of SQL statements were executed by a single sqlite_exec() call.
  • -} - -chng {2002 Aug 31 (2.7.1)} { -
  • Fix a bug in the ORDER BY logic that was introduced in version 2.7.0
  • -
  • C-style comments are now accepted by the tokenizer.
  • -
  • INSERT runs a little faster when the source is a SELECT statement.
  • -} - -chng {2002 Aug 25 (2.7.0)} { -
  • Make a distinction between numeric and text values when sorting. - Text values sort according to memcmp(). Numeric values sort in - numeric order.
  • -
  • Allow multiple simultaneous readers under windows by simulating - the reader/writers locks that are missing from Win95/98/ME.
  • -
  • An error is now returned when trying to start a transaction if - another transaction is already active.
  • -} - -chng {2002 Aug 12 (2.6.3)} { -
  • Add the ability to read both little-endian and big-endian databases. - So database created under SunOS or MacOSX can be read and written - under Linux or Windows and vice versa.
  • -
  • Convert to the new website: http://www.sqlite.org/
  • -
  • Allow transactions to span Linux Threads
  • -
  • Bug fix in the processing of the ORDER BY clause for GROUP BY queries
  • -} - -chng {2002 Jly 30 (2.6.2)} { -
  • Text files read by the COPY command can now have line terminators - of LF, CRLF, or CR.
  • -
  • SQLITE_BUSY is handled correctly if encountered during database - initialization.
  • -
  • Fix to UPDATE triggers on TEMP tables.
  • -
  • Documentation updates.
  • -} - -chng {2002 Jly 19 (2.6.1)} { -
  • Include a static string in the library that responds to the RCS - "ident" command and which contains the library version number.
  • -
  • Fix an assertion failure that occurred when deleting all rows of - a table with the "count_changes" pragma turned on.
  • -
  • Better error reporting when problems occur during the automatic - 2.5.6 to 2.6.0 database format upgrade.
  • -} - -chng {2002 Jly 17 (2.6.0)} { -
  • Change the format of indices to correct a design flaw the originated - with version 2.1.0. *** This is an incompatible - file format change *** When version 2.6.0 or later of the - library attempts to open a database file created by version 2.5.6 or - earlier, it will automatically and irreversibly convert the file format. - Make backup copies of older database files before opening them with - version 2.6.0 of the library. -
  • -} - -chng {2002 Jly 7 (2.5.6)} { -
  • Fix more problems with rollback. Enhance the test suite to exercise - the rollback logic extensively in order to prevent any future problems. -
  • -} - -chng {2002 Jly 6 (2.5.5)} { -
  • Fix a bug which could cause database corruption during a rollback. - This bugs was introduced in version 2.4.0 by the freelist - optimization of checking [410].
  • -
  • Fix a bug in aggregate functions for VIEWs.
  • -
  • Other minor changes and enhancements.
  • -} - -chng {2002 Jly 1 (2.5.4)} { -
  • Make the "AS" keyword optional again.
  • -
  • The datatype of columns now appear in the 4th argument to the - callback.
  • -
  • Added the sqlite_open_aux_file() API, though it is still - mostly undocumented and untested.
  • -
  • Added additional test cases and fixed a few bugs that those - test cases found.
  • -} - -chng {2002 Jun 24 (2.5.3)} { -
  • Bug fix: Database corruption can occur due to the optimization - that was introduced in version 2.4.0 (check-in [410]). The problem - should now be fixed. The use of versions 2.4.0 through 2.5.2 is - not recommended.
  • -} - -chng {2002 Jun 24 (2.5.2)} { -
  • Added the new SQLITE_TEMP_MASTER table which records the schema - for temporary tables in the same way that SQLITE_MASTER does for - persistent tables.
  • -
  • Added an optimization to UNION ALL
  • -
  • Fixed a bug in the processing of LEFT OUTER JOIN
  • -
  • The LIMIT clause now works on subselects
  • -
  • ORDER BY works on subselects
  • -
  • There is a new TypeOf() function used to determine if an expression - is numeric or text.
  • -
  • Autoincrement now works for INSERT from a SELECT.
  • -} - -chng {2002 Jun 19 (2.5.1)} { -
  • The query optimizer now attempts to implement the ORDER BY clause - using an index. Sorting is still used if not suitable index is - available.
  • -} - -chng {2002 Jun 17 (2.5.0)} { -
  • Added support for row triggers.
  • -
  • Added SQL-92 compliant handling of NULLs.
  • -
  • Add support for the full SQL-92 join syntax and LEFT OUTER JOINs.
  • -
  • Double-quoted strings interpreted as column names not text literals.
  • -
  • Parse (but do not implement) foreign keys.
  • -
  • Performance improvements in the parser, pager, and WHERE clause code - generator.
  • -
  • Make the LIMIT clause work on subqueries. (ORDER BY still does not - work, though.)
  • -
  • Added the "%Q" expansion to sqlite_*_printf().
  • -
  • Bug fixes too numerous to mention (see the change log).
  • -} - -chng {2002 May 09 (2.4.12)} { -
  • Added logic to detect when the library API routines are called out - of sequence.
  • -} - -chng {2002 May 08 (2.4.11)} { -
  • Bug fix: Column names in the result set were not being generated - correctly for some (rather complex) VIEWs. This could cause a - segfault under certain circumstances.
  • -} - -chng {2002 May 02 (2.4.10)} { -
  • Bug fix: Generate correct column headers when a compound SELECT is used - as a subquery.
  • -
  • Added the sqlite_encode_binary() and sqlite_decode_binary() functions to - the source tree. But they are not yet linked into the library.
  • -
  • Documentation updates.
  • -
  • Export the sqlite_changes() function from windows DLLs.
  • -
  • Bug fix: Do not attempt the subquery flattening optimization on queries - that lack a FROM clause. To do so causes a segfault.
  • -} - -chng {2002 Apr 21 (2.4.9)} { -
  • Fix a bug that was causing the precompiled binary of SQLITE.EXE to - report "out of memory" under Windows 98.
  • -} - -chng {2002 Apr 20 (2.4.8)} { -
  • Make sure VIEWs are created after their corresponding TABLEs in the - output of the .dump command in the shell.
  • -
  • Speed improvements: Do not do synchronous updates on TEMP tables.
  • -
  • Many improvements and enhancements to the shell.
  • -
  • Make the GLOB and LIKE operators functions that can be overridden - by a programmer. This allows, for example, the LIKE operator to - be changed to be case sensitive.
  • -} - -chng {2002 Apr 06 (2.4.7)} { -
  • Add the ability to put TABLE.* in the column list of a - SELECT statement.
  • -
  • Permit SELECT statements without a FROM clause.
  • -
  • Added the last_insert_rowid() SQL function.
  • -
  • Do not count rows where the IGNORE conflict resolution occurs in - the row count.
  • -
  • Make sure functions expressions in the VALUES clause of an INSERT - are correct.
  • -
  • Added the sqlite_changes() API function to return the number - of row that changed in the most recent operation.
  • -} - -chng {2002 Apr 02 (2.4.6)} { -
  • Bug fix: Correctly handle terms in the WHERE clause of a join that - do not contain a comparison operator.
  • -} - -chng {2002 Apr 01 (2.4.5)} { -
  • Bug fix: Correctly handle functions that appear in the WHERE clause - of a join.
  • -
  • When the PRAGMA vdbe_trace=ON is set, correctly print the P3 operand - value when it is a pointer to a structure rather than a pointer to - a string.
  • -
  • When inserting an explicit NULL into an INTEGER PRIMARY KEY, convert - the NULL value into a unique key automatically.
  • -} - -chng {2002 Mar 24 (2.4.4)} { -
  • Allow "VIEW" to be a column name
  • -
  • Added support for CASE expressions (patch from Dan Kennedy)
  • -
  • Added RPMS to the delivery (patches from Doug Henry)
  • -
  • Fix typos in the documentation
  • -
  • Cut over configuration management to a new CVS repository with - its own CVSTrac bug tracking system.
  • -} - -chng {2002 Mar 22 (2.4.3)} { -
  • Fix a bug in SELECT that occurs when a compound SELECT is used as a - subquery in the FROM of a SELECT.
  • -
  • The sqlite_get_table() function now returns an error if you - give it two or more SELECTs that return different numbers of columns.
  • -} - -chng {2002 Mar 14 (2.4.2)} { -
  • Bug fix: Fix an assertion failure that occurred when ROWID was a column - in a SELECT statement on a view.
  • -
  • Bug fix: Fix an uninitialized variable in the VDBE that would could an - assert failure.
  • -
  • Make the os.h header file more robust in detecting when the compile is - for windows and when it is for unix.
  • -} - -chng {2002 Mar 13 (2.4.1)} { -
  • Using an unnamed subquery in a FROM clause would cause a segfault.
  • -
  • The parser now insists on seeing a semicolon or the end of input before - executing a statement. This avoids an accidental disaster if the - WHERE keyword is misspelled in an UPDATE or DELETE statement.
  • -} - - -chng {2002 Mar 10 (2.4.0)} { -
  • Change the name of the sanity_check PRAGMA to integrity_check - and make it available in all compiles.
  • -
  • SELECT min() or max() of an indexed column with no WHERE or GROUP BY - clause is handled as a special case which avoids a complete table scan.
  • -
  • Automatically generated ROWIDs are now sequential.
  • -
  • Do not allow dot-commands of the command-line shell to occur in the - middle of a real SQL command.
  • -
  • Modifications to the "lemon" parser generator so that the parser tables - are 4 times smaller.
  • -
  • Added support for user-defined functions implemented in C.
  • -
  • Added support for new functions: coalesce(), lower(), - upper(), and random() -
  • Added support for VIEWs.
  • -
  • Added the subquery flattening optimizer.
  • -
  • Modified the B-Tree and Pager modules so that disk pages that do not - contain real data (free pages) are not journaled and are not - written from memory back to the disk when they change. This does not - impact database integrity, since the - pages contain no real data, but it does make large INSERT operations - about 2.5 times faster and large DELETEs about 5 times faster.
  • -
  • Made the CACHE_SIZE pragma persistent
  • -
  • Added the SYNCHRONOUS pragma
  • -
  • Fixed a bug that was causing updates to fail inside of transactions when - the database contained a temporary table.
  • -} - -chng {2002 Feb 18 (2.3.3)} { -
  • Allow identifiers to be quoted in square brackets, for compatibility - with MS-Access.
  • -
  • Added support for sub-queries in the FROM clause of a SELECT.
  • -
  • More efficient implementation of sqliteFileExists() under Windows. - (by Joel Luscy)
  • -
  • The VALUES clause of an INSERT can now contain expressions, including - scalar SELECT clauses.
  • -
  • Added support for CREATE TABLE AS SELECT
  • -
  • Bug fix: Creating and dropping a table all within a single - transaction was not working.
  • -} - -chng {2002 Feb 14 (2.3.2)} { -
  • Bug fix: There was an incorrect assert() in pager.c. The real code was - all correct (as far as is known) so everything should work OK if you - compile with -DNDEBUG=1. When asserts are not disabled, there - could be a fault.
  • -} - -chng {2002 Feb 13 (2.3.1)} { -
  • Bug fix: An assertion was failing if "PRAGMA full_column_names=ON;" was - set and you did a query that used a rowid, like this: - "SELECT rowid, * FROM ...".
  • -} - -chng {2002 Jan 30 (2.3.0)} { -
  • Fix a serious bug in the INSERT command which was causing data to go - into the wrong columns if the data source was a SELECT and the INSERT - clauses specified its columns in some order other than the default.
  • -
  • Added the ability to resolve constraint conflicts is ways other than - an abort and rollback. See the documentation on the "ON CONFLICT" - clause for details.
  • -
  • Temporary files are now automatically deleted by the operating system - when closed. There are no more dangling temporary files on a program - crash. (If the OS crashes, fsck will delete the file after reboot - under Unix. I do not know what happens under Windows.)
  • -
  • NOT NULL constraints are honored.
  • -
  • The COPY command puts NULLs in columns whose data is '\N'.
  • -
  • In the COPY command, backslash can now be used to escape a newline.
  • -
  • Added the SANITY_CHECK pragma.
  • -} - -chng {2002 Jan 28 (2.2.5)} { -
  • Important bug fix: the IN operator was not working if either the - left-hand or right-hand side was derived from an INTEGER PRIMARY KEY.
  • -
  • Do not escape the backslash '\' character in the output of the - sqlite command-line access program.
  • -} - -chng {2002 Jan 22 (2.2.4)} { -
  • The label to the right of an AS in the column list of a SELECT can now - be used as part of an expression in the WHERE, ORDER BY, GROUP BY, and/or - HAVING clauses.
  • -
  • Fix a bug in the -separator command-line option to the sqlite - command.
  • -
  • Fix a problem with the sort order when comparing upper-case strings against - characters greater than 'Z' but less than 'a'.
  • -
  • Report an error if an ORDER BY or GROUP BY expression is constant.
  • -} - -chng {2002 Jan 16 (2.2.3)} { -
  • Fix warning messages in VC++ 7.0. (Patches from nicolas352001)
  • -
  • Make the library thread-safe. (The code is there and appears to work - but has not been stressed.)
  • -
  • Added the new sqlite_last_insert_rowid() API function.
  • -} - -chng {2002 Jan 13 (2.2.2)} { -
  • Bug fix: An assertion was failing when a temporary table with an index - had the same name as a permanent table created by a separate process.
  • -
  • Bug fix: Updates to tables containing an INTEGER PRIMARY KEY and an - index could fail.
  • -} - -chng {2002 Jan 9 (2.2.1)} { -
  • Bug fix: An attempt to delete a single row of a table with a WHERE - clause of "ROWID=x" when no such rowid exists was causing an error.
  • -
  • Bug fix: Passing in a NULL as the 3rd parameter to sqlite_open() - would sometimes cause a coredump.
  • -
  • Bug fix: DROP TABLE followed by a CREATE TABLE with the same name all - within a single transaction was causing a coredump.
  • -
  • Makefile updates from A. Rottmann
  • -} - -chng {2001 Dec 22 (2.2.0)} { -
  • Columns of type INTEGER PRIMARY KEY are actually used as the primary - key in underlying B-Tree representation of the table.
  • -
  • Several obscure, unrelated bugs were found and fixed while - implemented the integer primary key change of the previous bullet.
  • -
  • Added the ability to specify "*" as part of a larger column list in - the result section of a SELECT statement. For example: - "SELECT rowid, * FROM table1;".
  • -
  • Updates to comments and documentation.
  • -} - -chng {2001 Dec 14 (2.1.7)} { -
  • Fix a bug in CREATE TEMPORARY TABLE which was causing the - table to be initially allocated in the main database file instead - of in the separate temporary file. This bug could cause the library - to suffer an assertion failure and it could cause "page leaks" in the - main database file. -
  • Fix a bug in the b-tree subsystem that could sometimes cause the first - row of a table to be repeated during a database scan.
  • -} - -chng {2001 Dec 14 (2.1.6)} { -
  • Fix the locking mechanism yet again to prevent - sqlite_exec() from returning SQLITE_PROTOCOL - unnecessarily. This time the bug was a race condition in - the locking code. This change effects both POSIX and Windows users.
  • -} - -chng {2001 Dec 6 (2.1.5)} { -
  • Fix for another problem (unrelated to the one fixed in 2.1.4) - that sometimes causes sqlite_exec() to return SQLITE_PROTOCOL - unnecessarily. This time the bug was - in the POSIX locking code and should not effect windows users.
  • -} - -chng {2001 Dec 4 (2.1.4)} { -
  • Sometimes sqlite_exec() would return SQLITE_PROTOCOL when it - should have returned SQLITE_BUSY.
  • -
  • The fix to the previous bug uncovered a deadlock which was also - fixed.
  • -
  • Add the ability to put a single .command in the second argument - of the sqlite shell
  • -
  • Updates to the FAQ
  • -} - -chng {2001 Nov 23 (2.1.3)} { -
  • Fix the behavior of comparison operators - (ex: "<", "==", etc.) - so that they are consistent with the order of entries in an index.
  • -
  • Correct handling of integers in SQL expressions that are larger than - what can be represented by the machine integer.
  • -} - -chng {2001 Nov 22 (2.1.2)} { -
  • Changes to support 64-bit architectures.
  • -
  • Fix a bug in the locking protocol.
  • -
  • Fix a bug that could (rarely) cause the database to become - unreadable after a DROP TABLE due to corruption to the SQLITE_MASTER - table.
  • -
  • Change the code so that version 2.1.1 databases that were rendered - unreadable by the above bug can be read by this version of - the library even though the SQLITE_MASTER table is (slightly) - corrupted.
  • -} - -chng {2001 Nov 13 (2.1.1)} { -
  • Bug fix: Sometimes arbitrary strings were passed to the callback - function when the actual value of a column was NULL.
  • -} - -chng {2001 Nov 12 (2.1.0)} { -
  • Change the format of data records so that records up to 16MB in size - can be stored.
  • -
  • Change the format of indices to allow for better query optimization.
  • -
  • Implement the "LIMIT ... OFFSET ..." clause on SELECT statements.
  • -} - -chng {2001 Nov 3 (2.0.8)} { -
  • Made selected parameters in API functions const. This should - be fully backwards compatible.
  • -
  • Documentation updates
  • -
  • Simplify the design of the VDBE by restricting the number of sorters - and lists to 1. - In practice, no more than one sorter and one list was ever used anyhow. -
  • -} - -chng {2001 Oct 21 (2.0.7)} { -
  • Any UTF-8 character or ISO8859 character can be used as part of - an identifier.
  • -
  • Patches from Christian Werner to improve ODBC compatibility and to - fix a bug in the round() function.
  • -
  • Plug some memory leaks that use to occur if malloc() failed. - We have been and continue to be memory leak free as long as - malloc() works.
  • -
  • Changes to some test scripts so that they work on Windows in - addition to Unix.
  • -} - -chng {2001 Oct 19 (2.0.6)} { -
  • Added the EMPTY_RESULT_CALLBACKS pragma
  • -
  • Support for UTF-8 and ISO8859 characters in column and table names.
  • -
  • Bug fix: Compute correct table names with the FULL_COLUMN_NAMES pragma - is turned on.
  • -} - -chng {2001 Oct 14 (2.0.5)} { -
  • Added the COUNT_CHANGES pragma.
  • -
  • Changes to the FULL_COLUMN_NAMES pragma to help out the ODBC driver.
  • -
  • Bug fix: "SELECT count(*)" was returning NULL for empty tables. - Now it returns 0.
  • -} - -chng {2001 Oct 13 (2.0.4)} { -
  • Bug fix: an obscure and relatively harmless bug was causing one of - the tests to fail when gcc optimizations are turned on. This release - fixes the problem.
  • -} - -chng {2001 Oct 13 (2.0.3)} { -
  • Bug fix: the sqlite_busy_timeout() function was delaying 1000 - times too long before failing.
  • -
  • Bug fix: an assertion was failing if the disk holding the database - file became full or stopped accepting writes for some other reason. - New tests were added to detect similar problems in the future.
  • -
  • Added new operators: & (bitwise-and) - | (bitwise-or), ~ (ones-complement), - << (shift left), >> (shift right).
  • -
  • Added new functions: round() and abs().
  • -} - -chng {2001 Oct 9 (2.0.2)} { -
  • Fix two bugs in the locking protocol. (One was masking the other.)
  • -
  • Removed some unused "#include " that were causing problems - for VC++.
  • -
  • Fixed sqlite.h so that it is usable from C++
  • -
  • Added the FULL_COLUMN_NAMES pragma. When set to "ON", the names of - columns are reported back as TABLE.COLUMN instead of just COLUMN.
  • -
  • Added the TABLE_INFO() and INDEX_INFO() pragmas to help support the - ODBC interface.
  • -
  • Added support for TEMPORARY tables and indices.
  • -} - -chng {2001 Oct 2 (2.0.1)} { -
  • Remove some C++ style comments from btree.c so that it will compile - using compilers other than gcc.
  • -
  • The ".dump" output from the shell does not work if there are embedded - newlines anywhere in the data. This is an old bug that was carried - forward from version 1.0. To fix it, the ".dump" output no longer - uses the COPY command. It instead generates INSERT statements.
  • -
  • Extend the expression syntax to support "expr NOT NULL" (with a - space between the "NOT" and the "NULL") in addition to "expr NOTNULL" - (with no space).
  • -} - -chng {2001 Sep 28 (2.0.0)} { -
  • Automatically build binaries for Linux and Windows and put them on - the website.
  • -} - -chng {2001 Sep 28 (2.0-alpha-4)} { -
  • Incorporate makefile patches form A. Rottmann to use LIBTOOL
  • -} - -chng {2001 Sep 27 (2.0-alpha-3)} { -
  • SQLite now honors the UNIQUE keyword in CREATE UNIQUE INDEX. Primary - keys are required to be unique.
  • -
  • File format changed back to what it was for alpha-1
  • -
  • Fixes to the rollback and locking behavior
  • -} - -chng {2001 Sep 20 (2.0-alpha-2)} { -
  • Initial release of version 2.0. The idea of renaming the library - to "SQLus" was abandoned in favor of keeping the "SQLite" name and - bumping the major version number.
  • -
  • The pager and btree subsystems added back. They are now the only - available backend.
  • -
  • The Dbbe abstraction and the GDBM and memory drivers were removed.
  • -
  • Copyright on all code was disclaimed. The library is now in the - public domain.
  • -} - -chng {2001 Jul 23 (1.0.32)} { -
  • Pager and btree subsystems removed. These will be used in a follow-on - SQL server library named "SQLus".
  • -
  • Add the ability to use quoted strings as table and column names in - expressions.
  • -} - -chng {2001 Apr 14 (1.0.31)} { -
  • Pager subsystem added but not yet used.
  • -
  • More robust handling of out-of-memory errors.
  • -
  • New tests added to the test suite.
  • -} - -chng {2001 Apr 6 (1.0.30)} { -
  • Remove the sqlite_encoding TCL variable that was introduced - in the previous version.
  • -
  • Add options -encoding and -tcl-uses-utf to the - sqlite TCL command.
  • -
  • Add tests to make sure that tclsqlite was compiled using Tcl header - files and libraries that match.
  • -} - -chng {2001 Apr 5 (1.0.29)} { -
  • The library now assumes data is stored as UTF-8 if the --enable-utf8 - option is given to configure. The default behavior is to assume - iso8859-x, as it has always done. This only makes a difference for - LIKE and GLOB operators and the LENGTH and SUBSTR functions.
  • -
  • If the library is not configured for UTF-8 and the Tcl library - is one of the newer ones that uses UTF-8 internally, - then a conversion from UTF-8 to iso8859 and - back again is done inside the TCL interface.
  • -} - -chng {2001 Apr 4 (1.0.28)} { -
  • Added limited support for transactions. At this point, transactions - will do table locking on the GDBM backend. There is no support (yet) - for rollback or atomic commit.
  • -
  • Added special column names ROWID, OID, and _ROWID_ that refer to the - unique random integer key associated with every row of every table.
  • -
  • Additional tests added to the regression suite to cover the new ROWID - feature and the TCL interface bugs mentioned below.
  • -
  • Changes to the "lemon" parser generator to help it work better when - compiled using MSVC.
  • -
  • Bug fixes in the TCL interface identified by Oleg Oleinick.
  • -} - -chng {2001 Mar 20 (1.0.27)} { -
  • When doing DELETE and UPDATE, the library used to write the record - numbers of records to be deleted or updated into a temporary file. - This is changed so that the record numbers are held in memory.
  • -
  • The DELETE command without a WHILE clause just removes the database - files from the disk, rather than going through and deleting record - by record.
  • -} - -chng {2001 Mar 20 (1.0.26)} { -
  • A serious bug fixed on Windows. Windows users should upgrade. - No impact to Unix.
  • -} - -chng {2001 Mar 15 (1.0.25)} { -
  • Modify the test scripts to identify tests that depend on system - load and processor speed and - to warn the user that a failure of one of those (rare) tests does - not necessarily mean the library is malfunctioning. No changes to - code. -
  • -} - -chng {2001 Mar 14 (1.0.24)} { -
  • Fix a bug which was causing - the UPDATE command to fail on systems where "malloc(0)" returns - NULL. The problem does not appear Windows, Linux, or HPUX but does - cause the library to fail on QNX. -
  • -} - -chng {2001 Feb 19 (1.0.23)} { -
  • An unrelated (and minor) bug from Mark Muranwski fixed. The algorithm - for figuring out where to put temporary files for a "memory:" database - was not working quite right. -
  • -} - -chng {2001 Feb 19 (1.0.22)} { -
  • The previous fix was not quite right. This one seems to work better. -
  • -} - -chng {2001 Feb 19 (1.0.21)} { -
  • The UPDATE statement was not working when the WHERE clause contained - some terms that could be satisfied using indices and other terms that - could not. Fixed.
  • -} - -chng {2001 Feb 11 (1.0.20)} { -
  • Merge development changes into the main trunk. Future work toward - using a BTree file structure will use a separate CVS source tree. This - CVS tree will continue to support the GDBM version of SQLite only.
  • -} - -chng {2001 Feb 6 (1.0.19)} { -
  • Fix a strange (but valid) C declaration that was causing problems - for QNX. No logical changes.
  • -} - -chng {2001 Jan 4 (1.0.18)} { -
  • Print the offending SQL statement when an error occurs.
  • -
  • Do not require commas between constraints in CREATE TABLE statements.
  • -
  • Added the "-echo" option to the shell.
  • -
  • Changes to comments.
  • -} - -chng {2000 Dec 10 (1.0.17)} { -
  • Rewrote sqlite_complete() to make it faster.
  • -
  • Minor tweaks to other code to make it run a little faster.
  • -
  • Added new tests for sqlite_complete() and for memory leaks.
  • -} - -chng {2000 Dec 4 (1.0.16)} { -
  • Documentation updates. Mostly fixing of typos and spelling errors.
  • -} - -chng {2000 Oct 23 (1.0.15)} { -
  • Documentation updates
  • -
  • Some sanity checking code was removed from the inner loop of vdbe.c - to help the library to run a little faster. The code is only - removed if you compile with -DNDEBUG.
  • -} - -chng {2000 Oct 19 (1.0.14)} { -
  • Added a "memory:" backend driver that stores its database in an - in-memory hash table.
  • -} - -chng {2000 Oct 18 (1.0.13)} { -
  • Break out the GDBM driver into a separate file in anticipation - to added new drivers.
  • -
  • Allow the name of a database to be prefixed by the driver type. - For now, the only driver type is "gdbm:".
  • -} - -chng {2000 Oct 16 (1.0.12)} { -
  • Fixed an off-by-one error that was causing a coredump in - the '%q' format directive of the new - sqlite_..._printf() routines.
  • -
  • Added the sqlite_interrupt() interface.
  • -
  • In the shell, sqlite_interrupt() is invoked when the - user presses Control-C
  • -
  • Fixed some instances where sqlite_exec() was - returning the wrong error code.
  • -} - -chng {2000 Oct 11 (1.0.10)} { -
  • Added notes on how to compile for Windows95/98.
  • -
  • Removed a few variables that were not being used. Etc.
  • -} - -chng {2000 Oct 8 (1.0.9)} { -
  • Added the sqlite_..._printf() interface routines.
  • -
  • Modified the sqlite shell program to use the new interface - routines.
  • -
  • Modified the sqlite shell program to print the schema for - the built-in SQLITE_MASTER table, if explicitly requested.
  • -} - -chng {2000 Sep 30 (1.0.8)} { -
  • Begin writing documentation on the TCL interface.
  • -} - -chng {2000 Sep 29 (Not Released)} { -
  • Added the sqlite_get_table() API
  • -
  • Updated the documentation for due to the above change.
  • -
  • Modified the sqlite shell to make use of the new - sqlite_get_table() API in order to print a list of tables - in multiple columns, similar to the way "ls" prints filenames.
  • -
  • Modified the sqlite shell to print a semicolon at the - end of each CREATE statement in the output of the ".schema" command.
  • -} - -chng {2000 Sep 21 (Not Released)} { -
  • Change the tclsqlite "eval" method to return a list of results if - no callback script is specified.
  • -
  • Change tclsqlite.c to use the Tcl_Obj interface
  • -
  • Add tclsqlite.c to the libsqlite.a library
  • -} - -chng {2000 Sep 13 (Version 1.0.5)} { -
  • Changed the print format for floating point values from "%g" to "%.15g". -
  • -
  • Changed the comparison function so that numbers in exponential notation - (ex: 1.234e+05) sort in numerical order.
  • -} - -chng {2000 Aug 28 (Version 1.0.4)} { -
  • Added functions length() and substr().
  • -
  • Fix a bug in the sqlite shell program that was causing - a coredump when the output mode was "column" and the first row - of data contained a NULL.
  • -} - -chng {2000 Aug 22 (Version 1.0.3)} { -
  • In the sqlite shell, print the "Database opened READ ONLY" message - to stderr instead of stdout.
  • -
  • In the sqlite shell, now print the version number on initial startup.
  • -
  • Add the sqlite_version[] string constant to the library
  • -
  • Makefile updates
  • -
  • Bug fix: incorrect VDBE code was being generated for the following - circumstance: a query on an indexed table containing a WHERE clause with - an IN operator that had a subquery on its right-hand side.
  • -} - -chng {2000 Aug 18 (Version 1.0.1)} { -
  • Fix a bug in the configure script.
  • -
  • Minor revisions to the website.
  • -} - -chng {2000 Aug 17 (Version 1.0)} { -
  • Change the sqlite program so that it can read - databases for which it lacks write permission. (It used to - refuse all access if it could not write.)
  • -} - -chng {2000 Aug 9} { -
  • Treat carriage returns as white space.
  • -} - -chng {2000 Aug 8} { -
  • Added pattern matching to the ".table" command in the "sqlite" -command shell.
  • -} - -chng {2000 Aug 4} { -
  • Documentation updates
  • -
  • Added "busy" and "timeout" methods to the Tcl interface
  • -} - -chng {2000 Aug 3} { -
  • File format version number was being stored in sqlite_master.tcl - multiple times. This was harmless, but unnecessary. It is now fixed.
  • -} - -chng {2000 Aug 2} { -
  • The file format for indices was changed slightly in order to work - around an inefficiency that can sometimes come up with GDBM when - there are large indices having many entries with the same key. - ** Incompatible Change **
  • -} - -chng {2000 Aug 1} { -
  • The parser's stack was overflowing on a very long UPDATE statement. - This is now fixed.
  • -} - -chng {2000 July 31} { -
  • Finish the VDBE tutorial.
  • -
  • Added documentation on compiling to WindowsNT.
  • -
  • Fix a configuration program for WindowsNT.
  • -
  • Fix a configuration problem for HPUX.
  • -} - -chng {2000 July 29} { -
  • Better labels on column names of the result.
  • -} - -chng {2000 July 28} { -
  • Added the sqlite_busy_handler() - and sqlite_busy_timeout() interface.
  • -} - -chng {2000 June 23} { -
  • Begin writing the VDBE tutorial.
  • -} - -chng {2000 June 21} { -
  • Clean up comments and variable names. Changes to documentation. - No functional changes to the code.
  • -} - -chng {2000 June 19} { -
  • Column names in UPDATE statements were case sensitive. - This mistake has now been fixed.
  • -} - -chng {2000 June 16} { -
  • Added the concatenate string operator (||)
  • -} - -chng {2000 June 12} { -
  • Added the fcnt() function to the SQL interpreter. The fcnt() function - returns the number of database "Fetch" operations that have occurred. - This function is designed for use in test scripts to verify that - queries are efficient and appropriately optimized. Fcnt() has no other - useful purpose, as far as I know.
  • -
  • Added a bunch more tests that take advantage of the new fcnt() function. - The new tests did not uncover any new problems.
  • -} - -chng {2000 June 8} { -
  • Added lots of new test cases
  • -
  • Fix a few bugs discovered while adding test cases
  • -
  • Begin adding lots of new documentation
  • -} - -chng {2000 June 6} { -
  • Added compound select operators: UNION, UNION ALL, -INTERSECT, and EXCEPT
  • -
  • Added support for using (SELECT ...) within expressions
  • -
  • Added support for IN and BETWEEN operators
  • -
  • Added support for GROUP BY and HAVING
  • -
  • NULL values are now reported to the callback as a NULL pointer - rather than an empty string.
  • -} - -chng {2000 June 3} { -
  • Added support for default values on columns of a table.
  • -
  • Improved test coverage. Fixed a few obscure bugs found by the -improved tests.
  • -} - -chng {2000 June 2} { -
  • All database files to be modified by an UPDATE, INSERT or DELETE are -now locked before any changes are made to any files. -This makes it safe (I think) to access -the same database simultaneously from multiple processes.
  • -
  • The code appears stable so we are now calling it "beta".
  • -} - -chng {2000 June 1} { -
  • Better support for file locking so that two or more processes -(or threads) -can access the same database simultaneously. More work needed in -this area, though.
  • -} - -chng {2000 May 31} { -
  • Added support for aggregate functions (Ex: COUNT(*), MIN(...)) -to the SELECT statement.
  • -
  • Added support for SELECT DISTINCT ...
  • -} - -chng {2000 May 30} { -
  • Added the LIKE operator.
  • -
  • Added a GLOB operator: similar to LIKE -but it uses Unix shell globbing wildcards instead of the '%' -and '_' wildcards of SQL.
  • -
  • Added the COPY command patterned after -PostgreSQL so that SQLite -can now read the output of the pg_dump database dump utility -of PostgreSQL.
  • -
  • Added a VACUUM command that that calls the -gdbm_reorganize() function on the underlying database -files.
  • -
  • And many, many bug fixes...
  • -} - -chng {2000 May 29} { -
  • Initial Public Release of Alpha code
  • -} - -puts { -
    -} -footer {$Id:} diff --git a/sqlite/www/common.tcl b/sqlite/www/common.tcl deleted file mode 100644 index cb2d043..0000000 --- a/sqlite/www/common.tcl +++ /dev/null @@ -1,88 +0,0 @@ -# This file contains TCL procedures used to generate standard parts of -# web pages. -# - -proc header {txt} { - puts "$txt" - puts \ -{ - - - - - - - - -
    - - - - - -
    - - -
    } -} - -proc footer {{rcsid {}}} { - puts { - - -
    } - set date [lrange $rcsid 3 4] - if {$date!=""} { - puts "This page last modified on $date" - } - puts {} -} - - -# The following proc is used to ensure consistent formatting in the -# HTML generated by lang.tcl and pragma.tcl. -# -proc Syntax {args} { - puts {} - foreach {rule body} $args { - puts "" - regsub -all < $body {%LT} body - regsub -all > $body {%GT} body - regsub -all %LT $body {} body - regsub -all %GT $body {} body - regsub -all {[]|[*?]} $body {&} body - regsub -all "\n" [string trim $body] "
    \n" body - regsub -all "\n *" $body "\n\\ \\ \\ \\ " body - regsub -all {[|,.*()]} $body {&} body - regsub -all { = } $body { = } body - regsub -all {STAR} $body {*} body - ## These metacharacters must be handled to undo being - ## treated as SQL punctuation characters above. - regsub -all {RPPLUS} $body {
    )+} body - regsub -all {LP} $body {(} body - regsub -all {RP} $body {)} body - ## Place the left-hand side of the rule in the 2nd table column. - puts "" - } - puts {
    " - puts "$rule ::=$body
    } -} - diff --git a/sqlite/www/compile.tcl b/sqlite/www/compile.tcl deleted file mode 100644 index 5ac6c17..0000000 --- a/sqlite/www/compile.tcl +++ /dev/null @@ -1,272 +0,0 @@ -# -# Run this Tcl script to generate the compile.html file. -# -set rcsid {$Id: compile.tcl,v 1.4 2005/02/09 01:40:25 danielk1977 Exp $ } -source common.tcl -header {Compilation Options For SQLite} - -puts { -

    Compilation Options For SQLite

    - -

    -For most purposes, SQLite can be built just fine using the default -compilation options. However, if required, the compile-time options -documented below can be used to -omit SQLite features (resulting in -a smaller compiled library size) or to change the -default values of some parameters. -

    -

    -Every effort has been made to ensure that the various combinations -of compilation options work harmoniously and produce a working library. -Nevertheless, it is strongly recommended that the SQLite test-suite -be executed to check for errors before using an SQLite library built -with non-standard compilation options. -

    - -

    Options To Set Default Parameter Values

    - -

    SQLITE_DEFAULT_AUTOVACUUM=<1 or 0>
    -This macro determines if SQLite creates databases with the -auto-vacuum -flag set by default. The default value is 0 (do not create auto-vacuum -databases). In any case the compile-time default may be overridden by the -"PRAGMA auto_vacuum" command. -

    - -

    SQLITE_DEFAULT_CACHE_SIZE=<pages>
    -This macro sets the default size of the page-cache for each attached -database, in pages. This can be overridden by the "PRAGMA cache_size" -comamnd. The default value is 2000. -

    - -

    SQLITE_DEFAULT_PAGE_SIZE=<bytes>
    -This macro is used to set the default page-size used when a -database is created. The value assigned must be a power of 2. The -default value is 1024. The compile-time default may be overridden at -runtime by the "PRAGMA page_size" command. -

    - -

    SQLITE_DEFAULT_TEMP_CACHE_SIZE=<pages>
    -This macro sets the default size of the page-cache for temporary files -created by SQLite to store intermediate results, in pages. It does -not affect the page-cache for the temp database, where tables created -using "CREATE TEMP TABLE" are stored. The default value is 500. -

    - -

    SQLITE_MAX_PAGE_SIZE=<bytes>
    -This is used to set the maximum allowable page-size that can -be specified by the "PRAGMA page_size" command. The default value -is 8192. -

    - - -

    Options To Omit Features

    - -

    The following options are used to reduce the size of the compiled -library by omiting optional features. This is probably only useful -in embedded systems where space is especially tight, as even with all -features included the SQLite library is relatively small. Don't forget -to tell your compiler to optimize for binary size! (the -Os option if -using GCC).

    - -

    The macros in this section do not require values. The following -compilation switches all have the same effect:
    --DSQLITE_OMIT_ALTERTABLE
    --DSQLITE_OMIT_ALTERTABLE=1
    --DSQLITE_OMIT_ALTERTABLE=0 -

    - -

    If any of these options are defined, then the same set of SQLITE_OMIT_XXX -options must also be defined when using the 'lemon' tool to generate a parse.c -file. Because of this, these options may only used when the library is built -from source, not from the collection of pre-packaged C files provided for -non-UNIX like platforms on the website. -

    - -

    SQLITE_OMIT_ALTERTABLE
    -When this option is defined, the -ALTER TABLE command is not included in the -library. Executing an ALTER TABLE statement causes a parse error. -

    - -

    SQLITE_OMIT_AUTHORIZATION
    -Defining this option omits the authorization callback feature from the -library. The -sqlite3_set_authorizer() API function is not present in the library. -

    - -

    SQLITE_OMIT_AUTOVACUUM
    -If this option is defined, the library cannot create or write to -databases that support -auto-vacuum. Executing a -"PRAGMA auto_vacuum" statement is not an error, but does not return a value -or modify the auto-vacuum flag in the database file. If a database that -supports auto-vacuum is opened by a library compiled with this option, it -is automatically opened in read-only mode. -

    - -

    SQLITE_OMIT_AUTOINCREMENT
    -This option is used to omit the AUTOINCREMENT functionality. When this -is macro is defined, columns declared as "INTEGER PRIMARY KEY AUTOINCREMENT" -behave in the same way as columns declared as "INTEGER PRIMARY KEY" when a -NULL is inserted. The sqlite_sequence system table is neither created, nor -respected if it already exists. -

    -

    TODO: Need a link here - AUTOINCREMENT is not yet documented

    - -

    SQLITE_OMIT_BLOB_LITERAL
    -When this option is defined, it is not possible to specify a blob in -an SQL statement using the X'ABCD' syntax.

    -

    WARNING: The VACUUM command depends on this syntax for vacuuming databases -that contain blobs, so disabling this functionality may render a database -unvacuumable. -

    -

    TODO: Need a link here - is that syntax documented anywhere?

    - -

    SQLITE_OMIT_COMPOUND_SELECT
    -This option is used to omit the compound SELECT functionality. -SELECT statements that use the -UNION, UNION ALL, INTERSECT or EXCEPT compound SELECT operators will -cause a parse error. -

    - -

    SQLITE_OMIT_CONFLICT_CLAUSE
    -In the future, this option will be used to omit the -ON CONFLICT clause from the library. -

    - -

    SQLITE_OMIT_DATETIME_FUNCS
    -If this option is defined, SQLite's built-in date and time manipulation -functions are omitted. Specifically, the SQL functions julianday(), date(), -time(), datetime() and strftime() are not available. The default column -values CURRENT_TIME, CURRENT_DATE and CURRENT_DATETIME are still available. -

    - -

    SQLITE_OMIT_EXPLAIN
    -Defining this option causes the EXPLAIN command to be omitted from the -library. Attempting to execute an EXPLAIN statement will cause a parse -error. -

    - -

    SQLITE_OMIT_FLOATING_POINT
    -This option is used to omit floating-point number support from the SQLite -library. When specified, specifying a floating point number as a literal -(i.e. "1.01") results in a parse error. -

    -

    In the future, this option may also disable other floating point -functionality, for example the sqlite3_result_double(), -sqlite3_bind_double(), sqlite3_value_double() and sqlite3_column_double() -API functions. -

    - -

    SQLITE_OMIT_FOREIGN_KEY
    -If this option is defined, FOREIGN KEY clauses in column declarations are -ignored. -

    - -

    SQLITE_OMIT_INTEGRITY_CHECK
    -This option may be used to omit the -"PRAGMA integrity_check" -command from the compiled library. -

    - -

    SQLITE_OMIT_MEMORYDB
    -When this is defined, the library does not respect the special database -name ":memory:" (normally used to create an in-memory database). If -":memory:" is passed to sqlite3_open(), a file with this name will be -opened or created. -

    - -

    SQLITE_OMIT_PAGER_PRAGMAS
    -Defining this option omits pragmas related to the pager subsystem from -the build. Currently, the -default_cache_size and -cache_size pragmas are omitted. -

    - -

    SQLITE_OMIT_PRAGMA
    -This option is used to omit the PRAGMA command -from the library. Note that it is useful to define the macros that omit -specific pragmas in addition to this, as they may also remove supporting code -in other sub-systems. This macro removes the PRAGMA command only. -

    - -

    SQLITE_OMIT_PROGRESS_CALLBACK
    -This option may be defined to omit the capability to issue "progress" -callbacks during long-running SQL statements. The -sqlite3_progress_handler() -API function is not present in the library. - -

    SQLITE_OMIT_REINDEX
    -When this option is defined, the REINDEX -command is not included in the library. Executing a REINDEX statement causes -a parse error. -

    - -

    SQLITE_OMIT_SCHEMA_PRAGMAS
    -Defining this option omits pragmas for querying the database schema from -the build. Currently, the -table_info, -index_info, -index_list and -database_list -pragmas are omitted. -

    - -

    SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
    -Defining this option omits pragmas for querying and modifying the -database schema version and user version from the build. Specifically, the -schema_version and -user_version -pragmas are omitted. - -

    SQLITE_OMIT_SUBQUERY
    -

    If defined, support for sub-selects and the IN() operator are omitted. -

    - -

    SQLITE_OMIT_TCL_VARIABLE
    -

    If this macro is defined, then the special "$" syntax -used to automatically bind SQL variables to TCL variables is omitted. -

    - -

    SQLITE_OMIT_TRIGGER
    -Defining this option omits support for VIEW objects. Neither the -CREATE TRIGGER or -DROP TRIGGER -commands are available in this case, attempting to execute either will result -in a parse error. -

    -

    -WARNING: If this macro is defined, it will not be possible to open a database -for which the schema contains TRIGGER objects. -

    - -

    SQLITE_OMIT_UTF16
    -This macro is used to omit support for UTF16 text encoding. When this is -defined all API functions that return or accept UTF16 encoded text are -unavailable. These functions can be identified by the fact that they end -with '16', for example sqlite3_prepare16(), sqlite3_column_text16() and -sqlite3_bind_text16(). -

    - -

    SQLITE_OMIT_VACUUM
    -When this option is defined, the VACUUM -command is not included in the library. Executing a VACUUM statement causes -a parse error. -

    - -

    SQLITE_OMIT_VIEW
    -Defining this option omits support for VIEW objects. Neither the -CREATE VIEW or -DROP VIEW -commands are available in this case, attempting to execute either will result -in a parse error. -

    -

    -WARNING: If this macro is defined, it will not be possible to open a database -for which the schema contains VIEW objects. -

    -} -footer $rcsid - diff --git a/sqlite/www/datatype3.tcl b/sqlite/www/datatype3.tcl deleted file mode 100644 index f82929d..0000000 --- a/sqlite/www/datatype3.tcl +++ /dev/null @@ -1,421 +0,0 @@ -set rcsid {$Id: datatype3.tcl,v 1.10 2004/11/19 11:59:24 danielk1977 Exp $} -source common.tcl -header {Datatypes In SQLite Version 3} -puts { -

    Datatypes In SQLite Version 3

    - -

    1. Storage Classes

    - -

    Version 2 of SQLite stores all column values as ASCII text. -Version 3 enhances this by providing the ability to store integer and -real numbers in a more compact format and the capability to store -BLOB data.

    - -

    Each value stored in an SQLite database (or manipulated by the -database engine) has one of the following storage classes:

    -
      -
    • NULL. The value is a NULL value.

      -
    • INTEGER. The value is a signed integer, stored in 1, - 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value.

      -
    • REAL. The value is a floating point value, stored as - an 8-byte IEEE floating point number.

      -
    • TEXT. The value is a text string, stored using the - database encoding (UTF-8, UTF-16BE or UTF-16-LE).

      -
    • BLOB. The value is a blob of data, stored exactly as - it was input.

      -
    - -

    As in SQLite version 2, any column in a version 3 database except an INTEGER -PRIMARY KEY may be used to store any type of value. The exception to -this rule is described below under 'Strict Affinity Mode'.

    - -

    All values supplied to SQLite, whether as literals embedded in SQL -statements or values bound to pre-compiled SQL statements -are assigned a storage class before the SQL statement is executed. -Under circumstances described below, the -database engine may convert values between numeric storage classes -(INTEGER and REAL) and TEXT during query execution. -

    - -

    Storage classes are initially assigned as follows:

    -
      -
    • Values specified as literals as part of SQL statements are - assigned storage class TEXT if they are enclosed by single or double - quotes, INTEGER if the literal is specified as an unquoted number - with no decimal point or exponent, REAL if the literal is an - unquoted number with a decimal point or exponent and NULL if the - value is a NULL. Literals with storage class BLOB are specified - using the X'ABCD' notation.

      -
    • Values supplied using the sqlite3_bind_* APIs are assigned - the storage class that most closely matches the native type bound - (i.e. sqlite3_bind_blob() binds a value with storage class BLOB).

      -
    -

    The storage class of a value that is the result of an SQL scalar -operator depends on the outermost operator of the expression. -User-defined functions may return values with any storage class. It -is not generally possible to determine the storage class of the -result of an expression at compile time.

    - -

    2. Column Affinity

    - -

    -In SQLite version 3, the type of a value is associated with the value -itself, not with the column or variable in which the value is stored. -(This is sometimes called - -manifest typing.) -All other SQL databases engines that we are aware of use the more -restrictive system of static typing where the type is associated with -the container, not the value. -

    - -

    -In order to maximize compatibility between SQLite and other database -engines, SQLite support the concept of "type affinity" on columns. -The type affinity of a column is the recommended type for data stored -in that column. The key here is that the type is recommended, not -required. Any column can still store any type of data, in theory. -It is just that some columns, given the choice, will prefer to use -one storage class over another. The preferred storage class for -a column is called its "affinity". -

    - -

    Each column in an SQLite 3 database is assigned one of the -following type affinities:

    -
      -
    • TEXT
    • -
    • NUMERIC
    • -
    • INTEGER
    • -
    • NONE
    • -
    - -

    A column with TEXT affinity stores all data using storage classes -NULL, TEXT or BLOB. If numerical data is inserted into a column with -TEXT affinity it is converted to text form before being stored.

    - -

    A column with NUMERIC affinity may contain values using all five -storage classes. When text data is inserted into a NUMERIC column, an -attempt is made to convert it to an integer or real number before it -is stored. If the conversion is successful, then the value is stored -using the INTEGER or REAL storage class. If the conversion cannot be -performed the value is stored using the TEXT storage class. No -attempt is made to convert NULL or blob values.

    - -

    A column that uses INTEGER affinity behaves in the same way as a -column with NUMERIC affinity, except that if a real value with no -floating point component (or text value that converts to such) is -inserted it is converted to an integer and stored using the INTEGER -storage class.

    - -

    A column with affinity NONE does not prefer one storage class over -another. It makes no attempt to coerce data before -it is inserted.

    - -

    2.1 Determination Of Column Affinity

    - -

    The type affinity of a column is determined by the declared type -of the column, according to the following rules:

    -
      -
    1. If the datatype contains the string "INT" then it - is assigned INTEGER affinity.

      - -
    2. If the datatype of the column contains any of the strings - "CHAR", "CLOB", or "TEXT" then that - column has TEXT affinity. Notice that the type VARCHAR contains the - string "CHAR" and is thus assigned TEXT affinity.

      - -
    3. If the datatype for a column - contains the string "BLOB" or if - no datatype is specified then the column has affinity NONE.

      - -
    4. Otherwise, the affinity is NUMERIC.

      -
    - -

    If a table is created using a "CREATE TABLE <table> AS -SELECT..." statement, then all columns have no datatype specified -and they are given no affinity.

    - -

    2.2 Column Affinity Example

    - -
    -
    CREATE TABLE t1(
    -    t  TEXT,
    -    nu NUMERIC, 
    -    i  INTEGER,
    -    no BLOB
    -);
    -
    --- Storage classes for the following row:
    --- TEXT, REAL, INTEGER, TEXT
    -INSERT INTO t1 VALUES('500.0', '500.0', '500.0', '500.0');
    -
    --- Storage classes for the following row:
    --- TEXT, REAL, INTEGER, REAL
    -INSERT INTO t1 VALUES(500.0, 500.0, 500.0, 500.0);
    -
    -
    - -

    3. Comparison Expressions

    - -

    Like SQLite version 2, version 3 -features the binary comparison operators '=', -'<', '<=', '>=' and '!=', an operation to test for set -membership, 'IN', and the ternary comparison operator 'BETWEEN'.

    -

    The results of a comparison depend on the storage classes of the -two values being compared, according to the following rules:

    -
      -
    • A value with storage class NULL is considered less than any - other value (including another value with storage class NULL).

      - -
    • An INTEGER or REAL value is less than any TEXT or BLOB value. - When an INTEGER or REAL is compared to another INTEGER or REAL, a - numerical comparison is performed.

      - -
    • A TEXT value is less than a BLOB value. When two TEXT values - are compared, the C library function memcmp() is usually used to - determine the result. However this can be overridden, as described - under 'User-defined collation Sequences' below.

      - -
    • When two BLOB values are compared, the result is always - determined using memcmp().

      -
    - -

    SQLite may attempt to convert values between the numeric storage -classes (INTEGER and REAL) and TEXT before performing a comparison. -For binary comparisons, this is done in the cases enumerated below. -The term "expression" used in the bullet points below means any -SQL scalar expression or literal other than a column value.

    -
      -
    • When a column value is compared to the result of an - expression, the affinity of the column is applied to the result of - the expression before the comparison takes place.

      - -
    • When two column values are compared, if one column has - INTEGER or NUMERIC affinity and the other does not, the NUMERIC - affinity is applied to any values with storage class TEXT extracted - from the non-NUMERIC column.

      - -
    • When the results of two expressions are compared, the no - conversions occur. The results are compared as is. If a string - is compared to a number, the number will always be less than the - string.

      -
    - -

    -In SQLite, the expression "a BETWEEN b AND c" is equivalent to "a >= b -AND a <= c", even if this means that different affinities are applied to -'a' in each of the comparisons required to evaluate the expression. -

    - -

    Expressions of the type "a IN (SELECT b ....)" are handled by the three -rules enumerated above for binary comparisons (e.g. in a -similar manner to "a = b"). For example if 'b' is a column value -and 'a' is an expression, then the affinity of 'b' is applied to 'a' -before any comparisons take place.

    - -

    SQLite treats the expression "a IN (x, y, z)" as equivalent to "a = z OR -a = y OR a = z". -

    - -

    3.1 Comparison Example

    - -
    -
    -CREATE TABLE t1(
    -    a TEXT,
    -    b NUMERIC,
    -    c BLOB
    -);
    -
    --- Storage classes for the following row:
    --- TEXT, REAL, TEXT
    -INSERT INTO t1 VALUES('500', '500', '500');
    -
    --- 60 and 40 are converted to '60' and '40' and values are compared as TEXT.
    -SELECT a < 60, a < 40 FROM t1;
    -1|0
    -
    --- Comparisons are numeric. No conversions are required.
    -SELECT b < 60, b < 600 FROM t1;
    -0|1
    -
    --- Both 60 and 600 (storage class NUMERIC) are less than '500'
    --- (storage class TEXT).
    -SELECT c < 60, c < 600 FROM t1;
    -0|0
    -
    -
    -

    4. Operators

    - -

    All mathematical operators (which is to say, all operators other -than the concatenation operator "||") apply NUMERIC -affinity to all operands prior to being carried out. If one or both -operands cannot be converted to NUMERIC then the result of the -operation is NULL.

    - -

    For the concatenation operator, TEXT affinity is applied to both -operands. If either operand cannot be converted to TEXT (because it -is NULL or a BLOB) then the result of the concatenation is NULL.

    - -

    5. Sorting, Grouping and Compound SELECTs

    - -

    When values are sorted by an ORDER by clause, values with storage -class NULL come first, followed by INTEGER and REAL values -interspersed in numeric order, followed by TEXT values usually in -memcmp() order, and finally BLOB values in memcmp() order. No storage -class conversions occur before the sort.

    - -

    When grouping values with the GROUP BY clause values with -different storage classes are considered distinct, except for INTEGER -and REAL values which are considered equal if they are numerically -equal. No affinities are applied to any values as the result of a -GROUP by clause.

    - -

    The compound SELECT operators UNION, -INTERSECT and EXCEPT perform implicit comparisons between values. -Before these comparisons are performed an affinity may be applied to -each value. The same affinity, if any, is applied to all values that -may be returned in a single column of the compound SELECT result set. -The affinity applied is the affinity of the column returned by the -left most component SELECTs that has a column value (and not some -other kind of expression) in that position. If for a given compound -SELECT column none of the component SELECTs return a column value, no -affinity is applied to the values from that column before they are -compared.

    - -

    6. Other Affinity Modes

    - -

    The above sections describe the operation of the database engine -in 'normal' affinity mode. SQLite version 3 will feature two other affinity -modes, as follows:

    -
      -
    • Strict affinity mode. In this mode if a conversion - between storage classes is ever required, the database engine - returns an error and the current statement is rolled back.

      - -
    • No affinity mode. In this mode no conversions between - storage classes are ever performed. Comparisons between values of - different storage classes (except for INTEGER and REAL) are always - false.

      -
    - - -

    7. User-defined Collation Sequences

    - -

    -By default, when SQLite compares two text values, the result of the -comparison is determined using memcmp(), regardless of the encoding of the -string. SQLite v3 provides the ability for users to supply arbitrary -comparison functions, known as user-defined collation sequences, to be used -instead of memcmp(). -

    -

    -Aside from the default collation sequence BINARY, implemented using -memcmp(), SQLite features two extra built-in collation sequences -intended for testing purposes, NOCASE and REVERSE: -

    -
      -
    • BINARY - Compares string data using memcmp(), regardless - of text encoding.
    • -
    • REVERSE - Collate in the reverse order to BINARY.
    • -
    • NOCASE - The same as binary, except the 26 upper case - characters used by the English language are - folded to their lower case equivalents before - the comparison is performed.
    - - -

    7.1 Assigning Collation Sequences from SQL

    - -

    -Each column of each table has a default collation type. If a collation type -other than BINARY is required, a COLLATE clause is specified as part of the -column definition to define it. -

    - -

    -Whenever two text values are compared by SQLite, a collation sequence is -used to determine the results of the comparison according to the following -rules. Sections 3 and 5 of this document describe the circumstances under -which such a comparison takes place. -

    - -

    -For binary comparison operators (=, <, >, <= and >=) if either operand is a -column, then the default collation type of the column determines the -collation sequence to use for the comparison. If both operands are columns, -then the collation type for the left operand determines the collation -sequence used. If neither operand is a column, then the BINARY collation -sequence is used. -

    - -

    -The expression "x BETWEEN y and z" is equivalent to "x >= y AND x <= -z". The expression "x IN (SELECT y ...)" is handled in the same way as the -expression "x = y" for the purposes of determining the collation sequence -to use. The collation sequence used for expressions of the form "x IN (y, z -...)" is the default collation type of x if x is a column, or BINARY -otherwise. -

    - -

    -An ORDER BY clause that is part of a SELECT -statement may be assigned a collation sequence to be used for the sort -operation explicitly. In this case the explicit collation sequence is -always used. Otherwise, if the expression sorted by an ORDER BY clause is -a column, then the default collation type of the column is used to -determine sort order. If the expression is not a column, then the BINARY -collation sequence is used. -

    - -

    7.2 Collation Sequences Example

    -

    -The examples below identify the collation sequences that would be used to -determine the results of text comparisons that may be performed by various -SQL statements. Note that a text comparison may not be required, and no -collation sequence used, in the case of numeric, blob or NULL values. -

    -
    -
    -CREATE TABLE t1(
    -    a,                 -- default collation type BINARY
    -    b COLLATE BINARY,  -- default collation type BINARY
    -    c COLLATE REVERSE, -- default collation type REVERSE
    -    d COLLATE NOCASE   -- default collation type NOCASE
    -);
    -
    --- Text comparison is performed using the BINARY collation sequence.
    -SELECT (a = b) FROM t1;
    -
    --- Text comparison is performed using the NOCASE collation sequence.
    -SELECT (a = d) FROM t1;
    -
    --- Text comparison is performed using the BINARY collation sequence.
    -SELECT (d = a) FROM t1;
    -
    --- Text comparison is performed using the REVERSE collation sequence.
    -SELECT ('abc' = c) FROM t1;
    -
    --- Text comparison is performed using the REVERSE collation sequence.
    -SELECT (c = 'abc') FROM t1;
    -
    --- Grouping is performed using the NOCASE collation sequence (i.e. values
    --- 'abc' and 'ABC' are placed in the same group).
    -SELECT count(*) GROUP BY d FROM t1;
    -
    --- Grouping is performed using the BINARY collation sequence.
    -SELECT count(*) GROUP BY (d || '') FROM t1;
    -
    --- Sorting is performed using the REVERSE collation sequence.
    -SELECT * FROM t1 ORDER BY c;
    -
    --- Sorting is performed using the BINARY collation sequence.
    -SELECT * FROM t1 ORDER BY (c || '');
    -
    --- Sorting is performed using the NOCASE collation sequence.
    -SELECT * FROM t1 ORDER BY c COLLATE NOCASE;
    -
    -
    -
    - -} -footer $rcsid diff --git a/sqlite/www/different.tcl b/sqlite/www/different.tcl deleted file mode 100644 index c529f62..0000000 --- a/sqlite/www/different.tcl +++ /dev/null @@ -1,140 +0,0 @@ -set rcsid {$Id: different.tcl,v 1.2 2005/01/20 22:48:49 drh Exp $} -source common.tcl -header {Distinctive Features Of SQLite} -puts { -

    -This page highlights some of the characteristics of SQLite that are -unusual and which make SQLite different from many other SQL -database engines. -

    -} -proc feature {tag name text} { - puts "" - puts "

    $name

    \n" - puts "
    $text
    \n" -} - -feature zeroconfig {Zero-Configuration} { - SQLite does not need to be "installed" before it is used. - There is no "setup" procedure. There is no - server process that needs to be started, stopped, or configured. - There is - no need for an administrator to create a new database instance or assign - access permissions to users. - SQLite uses no configuration files. - Nothing needs to be done to tell the system that SQLite is running. - No actions are required to recover after a system crash or power failure. - There is nothing to troubleshoot. -

    - SQLite just works. -

    - Other more familiar database engines run great once you get them going. - But doing the initial installation and configuration can be - intimidatingly complex. -} - -feature serverless {Serverless} { - Most SQL database engines are implemented as a separate server - process. Programs that want to access the database communicate - with the server using some kind of interprocess communcation - (typically TCP/IP) to send requests to the server and to receive - back results. SQLite does not work this way. With SQLite, the - process that wants to access the database reads and writes - directly from the database files on disk. There is no intermediary - server process. -

    - There are advantages and disadvantages to being serverless. The - main advantage is that there is no separate server process - to install, setup, configure, initialize, manage, and troubleshoot. - This is one reason why SQLite is a "zero-configuration" database - engine. Programs that use SQLite require no administrative support - for setting up the database engine before they are run. Any program - that is able to access the disk is able to use an SQLite database. -

    - On the other hand, a database engine that uses a server can provide - better protection from bugs in the client application - stray pointers - in a client cannot corrupt memory on the server. And because a server - is a single persistent process, it is able control database access with - more precision, allowing for finer grain locking and better concurrancy. -

    - Most SQL database engines are client/server based. Of those that are - serverless, SQLite is the only one that this author knows of that - allows multiple applications to access the same database at the same time. -} - -feature onefile {Single Database File} { - An SQLite database is a single ordinary disk file that can be located - anywhere in the directory hierarchy. If SQLite can read - the disk file then it can read anything in the database. If the disk - file and its directory are writable, then SQLite can change anything - in the database. Database files can easily be copied onto a USB - memory stick or emailed for sharing. -

    - Other SQL database engines tend to store data as a large collection of - files. Often these files are in a standard location that only the - database engine itself can access. This makes the data more secure, - but also makes it harder to access. Some SQL database engines provide - the option of writing directly to disk and bypassing the filesystem - all together. This provides added performance, but at the cost of - considerable setup and maintenance complexity. -} - -feature small {Compact} { - When optimized for size, the whole SQLite library with everything enabled - is less than 220KiB in size (as measured on an ix86 using the "size" - utility from the GNU compiler suite.) Unneeded features can be disabled - at compile-time to further reduce the size of the library to under - 170KiB if desired. -

    - Most other SQL database engines are much larger than this. IBM boasts - that it's recently released CloudScape database engine is "only" a 2MiB - jar file - 10 times larger than SQLite even after it is compressed! - Firefox boasts that it's client-side library is only 350KiB. That's - 50% larger than SQLite and does not even contain the database engine. - The Berkeley DB library from Sleepycat is 450KiB and it lacks a schema - layer. -} - -feature typing {Manifest typing} { - -} - -feature readable {Readable source code} { -} - -feature vdbe {SQL statements compile into virtual machine code} { -} - -feature binding {Tight bindings to dynamic languages} { -} - -feature license {Public domain} { - The source code for SQLite is in the public domain. No claim of copyright - is made on any part of the core source code. (The documentation and test - code is a different matter - some sections of documentation and test logic - are governed by open-sources licenses.) All contributors to the - SQLite core software have signed releases specifically disavowing any - copyright interest in the code. This means that anybody is able to legally - do anything they want with the SQLite source code. -

    - There are other SQL database engines with liberal licenses that allow - the code to be broadly and freely used. But those other engines are - still governed by copyright law. SQLite is different in that copyright - law simply does not apply. -

    - The source code files for other SQL database engines typically begin - with a comment describing your license rights to view and copy that file. - The SQLite source code contains no license since it is not governed by - copyright. Instead of a license, the SQLite source code offers 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.
    -
    -} - -feature extensions {SQL language extensions} { -} - - -footer $rcsid diff --git a/sqlite/www/docs.tcl b/sqlite/www/docs.tcl deleted file mode 100644 index 3985d96..0000000 --- a/sqlite/www/docs.tcl +++ /dev/null @@ -1,127 +0,0 @@ -# This script generates the "docs.html" page that describes various -# sources of documentation available for SQLite. -# -set rcsid {$Id: docs.tcl,v 1.9 2005/01/03 01:33:00 drh Exp $} -source common.tcl -header {SQLite Documentation} -puts { -

    Available Documentation

    - -} - -proc doc {name url desc} { - puts {" - puts {} - puts {} -} - -doc {Appropriate Uses For SQLite} {whentouse.html} { - This document describes situations where SQLite is an approriate - database engine to use versus situations where a client/server - database engine might be a better choice. -} - -doc {SQLite In 5 Minutes Or Less} {quickstart.html} { - A very quick introduction to programming with SQLite. -} - -doc {SQL Syntax} {lang.html} { - This document describes the SQL language that is understood by - SQLite. -} - -doc {Pragma commands} {pragma.html} { - This document describes SQLite performance tuning options and other - special purpose database commands. -} - -doc {Version 2 C/C++ API} {c_interface.html} { - A description of the C/C++ interface bindings for SQLite through version - 2.8 -} -doc {SQLite Version 3} {version3.html} { - A summary of of the changes between SQLite version 2.8 and SQLite version 3.0. -} -doc {Version 3 C/C++ API} {capi3.html} { - A description of the C/C++ interface bindings for SQLite version 3.0.0 - and following. -} -doc {Version 3 C/C++ API
    Reference} {capi3ref.html} { - This document describes each API function separately. -} - -doc {Tcl API} {tclsqlite.html} { - A description of the TCL interface bindings for SQLite. -} - -doc {Locking And Concurrency
    In SQLite Version 3} {lockingv3.html} { - A description of how the new locking code in version 3 increases - concurrancy and decreases the problem of writer starvation. -} - -doc {Version 2 DataTypes } {datatypes.html} { - A description of how SQLite version 2 handles SQL datatypes. - Short summary: Everything is a string. -} -doc {Version 3 DataTypes } {datatype3.html} { - SQLite version 3 introduces the concept of manifest typing, where the - type of a value is associated with the value itself, not the column that - it is stored in. - This page describes data typing for SQLite version 3 in further detail. -} - -doc {Release History} {changes.html} { - A chronology of SQLite releases going back to version 1.0.0 -} - -doc {Null Handling} {nulls.html} { - Different SQL database engines handle NULLs in different ways. The - SQL standards are ambiguous. This document describes how SQLite handles - NULLs in comparison with other SQL database engines. -} - -doc {Copyright} {copyright.html} { - SQLite is in the public domain. This document describes what that means - and the implications for contributors. -} - -doc {Unsupported SQL} {omitted.html} { - This page describes features of SQL that SQLite does not support. -} - -doc {Speed Comparison} {speed.html} { - The speed of version 2.7.6 of SQLite is compared against PostgreSQL and - MySQL. -} - -doc {Architecture} {arch.html} { - An architectural overview of the SQLite library, useful for those who want - to hack the code. -} - -doc {VDBE Tutorial} {vdbe.html} { - The VDBE is the subsystem within SQLite that does the actual work of - executing SQL statements. This page describes the principles of operation - for the VDBE in SQLite version 2.7. This is essential reading for anyone - who want to modify the SQLite sources. -} - -doc {VDBE Opcodes} {opcode.html} { - This document is an automatically generated description of the various - opcodes that the VDBE understands. Programmers can use this document as - a reference to better understand the output of EXPLAIN listings from - SQLite. -} - -doc {Compilation Options} {compile.html} { - This document describes the compile time options that may be set to - modify the default behaviour of the library or omit optional features - in order to reduce binary size. -} - -puts {
    } - regsub -all { +} $name {\ } name - puts "$name} - puts $desc - puts {
    } -footer $rcsid diff --git a/sqlite/www/download.tcl b/sqlite/www/download.tcl deleted file mode 100644 index 3f53463..0000000 --- a/sqlite/www/download.tcl +++ /dev/null @@ -1,151 +0,0 @@ -# -# Run this TCL script to generate HTML for the download.html file. -# -set rcsid {$Id: download.tcl,v 1.17 2005/01/21 21:22:52 drh Exp $} -source common.tcl -header {SQLite Download Page} - -puts { -

    SQLite Download Page

    - -} - -proc Product {pattern desc} { - regsub VERSION $pattern {([0-9][0-9a-z._]+)} p2 - set p2 [string map {* .*} $p2] - regsub VERSION $pattern {*} p3 - set flist [glob -nocomplain $p3] - foreach file [lsort -dict $flist] { - if {![regexp ^$p2\$ $file all version]} continue - regsub -all _ $version . version - set size [file size $file] - puts "" - puts "" - puts "" - regsub -all VERSION $desc $version d2 - puts "" - } -} -cd doc - -proc Heading {title} { - puts "" -} - -Heading {Precompiled Binaries for Linux} - -Product sqlite*-VERSION.bin.gz { - A statically linked command-line program for accessing and modifing - SQLite databases. - See the documentation for additional information. -} - -Product tclsqlite-VERSION.so.gz { - Bindings for TCL. You can import this shared library into either - tclsh or wish to get SQLite database access from Tcl/Tk. - See the documentation for details. -} - -Product sqlite-VERSION.so.gz { - A precompiled shared-library for Linux. This is the same as - tclsqlite.so.gz but without the TCL bindings. -} - -Product sqlite-devel-VERSION-1.i386.rpm { - RPM containing documentation, header files, and static library for - SQLite version VERSION. -} -Product sqlite-VERSION-1.i386.rpm { - RPM containing shared libraries and the sqlite command-line - program for SQLite version VERSION. -} - -Product sqlite_analyzer-VERSION.bin.gz { - An analysis program for database files compatible with SQLite - version VERSION. -} - -Heading {Precompiled Binaries For Windows} - -Product sqlite-VERSION.zip { - A command-line program for accessing and modifing SQLite databases. - See the documentation for additional information. -} -Product tclsqlite-VERSION.zip { - Bindings for TCL. You can import this shared library into either - tclsh or wish to get SQLite database access from Tcl/Tk. - See the documentation for details. -} -Product sqlitedll-VERSION.zip { - This is a DLL of the SQLite library without the TCL bindings. - The only external dependency is MSVCRT.DLL. -} - -Product sqlite_analyzer-VERSION.zip { - An analysis program for database files compatible with SQLite version - VERSION. -} - - -Heading {Source Code} - -Product {sqlite-source-VERSION.zip} { - This ZIP archive contains pure C source code for the SQLite library. - Unlike the tarballs below, all of the preprocessing and automatic - code generation has already been done on these C source code, so they - can be processed directly with any ordinary C compiler. - This file is provided as a service to - MS-Windows users who lack the build support infrastructure of Unix. -} - -Product {sqlite-VERSION.src.rpm} { - An RPM containing complete source code for SQLite version VERSION -} - -Product {sqlite-VERSION.tar.gz} { - A tarball of the complete source tree for SQLite version VERSION - including all of the documentation. -} - -puts { -
    " - puts "$file
    ($size bytes)
    [string trim $d2]
    $title
    - - -

    Direct Access To The Sources Via Anonymous CVS

    - -

    -All SQLite source code is maintained in a -CVS repository that is -available for read-only access by anyone. You can -interactively view the -repository contents and download individual files -by visiting - -http://www.sqlite.org/cvstrac/dir?d=sqlite. -To access the repository directly, use the following -commands: -

    - -
    -cvs -d :pserver:anonymous@www.sqlite.org:/sqlite login
    -cvs -d :pserver:anonymous@www.sqlite.org:/sqlite checkout sqlite
    -
    - -

    -When the first command prompts you for a password, enter "anonymous". -

    - -

    -To access the SQLite version 2.8 sources, begin by getting the 3.0 -tree as described above. Then update to the "version_2" branch -as follows: -

    - -
    -cvs update -r version_2
    -
    - -} - -footer $rcsid diff --git a/sqlite/www/faq.tcl b/sqlite/www/faq.tcl deleted file mode 100644 index 9ffebb1..0000000 --- a/sqlite/www/faq.tcl +++ /dev/null @@ -1,505 +0,0 @@ -# -# Run this script to generated a faq.html output file -# -set rcsid {$Id: faq.tcl,v 1.28 2005/01/26 10:39:58 danielk1977 Exp $} -source common.tcl -header {SQLite Frequently Asked Questions} - -set cnt 1 -proc faq {question answer} { - set ::faq($::cnt) [list [string trim $question] [string trim $answer]] - incr ::cnt -} - -############# -# Enter questions and answers here. - -faq { - How do I create an AUTOINCREMENT field. -} { -

    Short answer: A column declared INTEGER PRIMARY KEY will - autoincrement.

    - -

    Here is the long answer: - Beginning with version SQLite 2.3.4, If you declare a column of - a table to be INTEGER PRIMARY KEY, then whenever you insert a NULL - into that column of the table, the NULL is automatically converted - into an integer which is one greater than the largest value of that - column over all other rows in the table, or 1 if the table is empty. - For example, suppose you have a table like this: -

    -CREATE TABLE t1(
    -  a INTEGER PRIMARY KEY,
    -  b INTEGER
    -);
    -
    -

    With this table, the statement

    -
    -INSERT INTO t1 VALUES(NULL,123);
    -
    -

    is logically equivalent to saying:

    -
    -INSERT INTO t1 VALUES((SELECT max(a) FROM t1)+1,123);
    -
    -

    For SQLite version 2.2.0 through 2.3.3, if you insert a NULL into - an INTEGER PRIMARY KEY column, the NULL will be changed to a unique - integer, but it will a semi-random integer. Unique keys generated this - way will not be sequential. For SQLite version 2.3.4 and beyond, the - unique keys will be sequential until the largest key reaches a value - of 2147483647. That is the largest 32-bit signed integer and cannot - be incremented, so subsequent insert attempts will revert to the - semi-random key generation algorithm of SQLite version 2.3.3 and - earlier.

    - -

    Beginning with version 2.2.3, there is a new API function named - sqlite_last_insert_rowid() which will return the integer key - for the most recent insert operation. See the API documentation for - details.

    - -

    SQLite version 3.0 expands the size of the rowid to 64 bits.

    -} - -faq { - What datatypes does SQLite support? -} { -

    SQLite ignores - the datatype information that follows the column name in CREATE TABLE. - You can put any type of data you want - into any column, without regard to the declared datatype of that column. -

    - -

    An exception to this rule is a column of type INTEGER PRIMARY KEY. - Such columns must hold an integer. An attempt to put a non-integer - value into an INTEGER PRIMARY KEY column will generate an error.

    - -

    There is a page on datatypes in SQLite - version 2.8 - and another for version 3.0 - that explains this concept further.

    -} - -faq { - SQLite lets me insert a string into a database column of type integer! -} { -

    This is a feature, not a bug. SQLite does not enforce data type - constraints. Any data can be - inserted into any column. You can put arbitrary length strings into - integer columns, floating point numbers in boolean columns, or dates - in character columns. The datatype you assign to a column in the - CREATE TABLE command does not restrict what data can be put into - that column. Every column is able to hold - an arbitrary length string. (There is one exception: Columns of - type INTEGER PRIMARY KEY may only hold an integer. An error will result - if you try to put anything other than an integer into an - INTEGER PRIMARY KEY column.)

    - -

    The datatype does effect how values are compared, however. For - columns with a numeric type (such as "integer") any string that looks - like a number is treated as a number for comparison and sorting purposes. - Consider these two command sequences:

    - -
    -CREATE TABLE t1(a INTEGER UNIQUE);        CREATE TABLE t2(b TEXT UNIQUE);
    -INSERT INTO t1 VALUES('0');               INSERT INTO t2 VALUES(0);
    -INSERT INTO t1 VALUES('0.0');             INSERT INTO t2 VALUES(0.0);
    -
    - -

    In the sequence on the left, the second insert will fail. In this case, - the strings '0' and '0.0' are treated as numbers since they are being - inserted into a numeric column and 0==0.0 which violates the uniqueness - constraint. But the second insert in the right-hand sequence works. In - this case, the constants 0 and 0.0 are treated a strings which means that - they are distinct.

    - -

    There is a page on datatypes in SQLite - version 2.8 - and another for version 3.0 - that explains this concept further.

    -} - -faq { - Why does SQLite think that the expression '0'=='00' is TRUE? -} { -

    As of version 2.7.0, it doesn't.

    - -

    But if one of the two values being compared is stored in a column that - has a numeric type, the the other value is treated as a number, not a - string and the result succeeds. For example:

    - -
    -CREATE TABLE t3(a INTEGER, b TEXT);
    -INSERT INTO t3 VALUES(0,0);
    -SELECT count(*) FROM t3 WHERE a=='00';
    -
    - -

    The SELECT in the above series of commands returns 1. The "a" column - is numeric so in the WHERE clause the string '00' is converted into a - number for comparison against "a". 0==00 so the test is true. Now - consider a different SELECT:

    - -
    -SELECT count(*) FROM t3 WHERE b=='00';
    -
    - -

    In this case the answer is 0. B is a text column so a text comparison - is done against '00'. '0'!='00' so the WHERE clause returns FALSE and - the count is zero.

    - -

    There is a page on datatypes in SQLite - version 2.8 - and another for version 3.0 - that explains this concept further.

    -} - -faq { - Why doesn't SQLite allow me to use '0' and '0.0' as the primary - key on two different rows of the same table? -} { -

    Your primary key must have a numeric type. Change the datatype of - your primary key to TEXT and it should work.

    - -

    Every row must have a unique primary key. For a column with a - numeric type, SQLite thinks that '0' and '0.0' are the - same value because they compare equal to one another numerically. - (See the previous question.) Hence the values are not unique.

    -} - -faq { - My linux box is not able to read an SQLite database that was created - on my SparcStation. -} { -

    You need to upgrade your SQLite library to version 2.6.3 or later.

    - -

    The x86 processor on your linux box is little-endian (meaning that - the least significant byte of integers comes first) but the Sparc is - big-endian (the most significant bytes comes first). SQLite databases - created on a little-endian architecture cannot be on a big-endian - machine by version 2.6.2 or earlier of SQLite. Beginning with - version 2.6.3, SQLite should be able to read and write database files - regardless of byte order of the machine on which the file was created.

    -} - -faq { - Can multiple applications or multiple instances of the same - application access a single database file at the same time? -} { -

    Multiple processes can have the same database open at the same - time. Multiple processes can be doing a SELECT - at the same time. But only one process can be making changes to - the database at once.

    - -

    Win95/98/ME lacks support for reader/writer locks in the operating - system. Prior to version 2.7.0, this meant that under windows you - could only have a single process reading the database at one time. - This problem was resolved in version 2.7.0 by implementing a user-space - probabilistic reader/writer locking strategy in the windows interface - code file. Windows - now works like Unix in allowing multiple simultaneous readers.

    - -

    The locking mechanism used to control simultaneous access might - not work correctly if the database file is kept on an NFS filesystem. - This is because file locking is broken on some NFS implementations. - You should avoid putting SQLite database files on NFS if multiple - processes might try to access the file at the same time. On Windows, - Microsoft's documentation says that locking may not work under FAT - filesystems if you are not running the Share.exe daemon. People who - have a lot of experience with Windows tell me that file locking of - network files is very buggy and is not dependable. If what they - say is true, sharing an SQLite database between two or more Windows - machines might cause unexpected problems.

    - -

    Locking in SQLite is very course-grained. SQLite locks the - entire database. Big database servers (PostgreSQL, Oracle, etc.) - generally have finer grained locking, such as locking on a single - table or a single row within a table. If you have a massively - parallel database application, you should consider using a big database - server instead of SQLite.

    - -

    When SQLite tries to access a file that is locked by another - process, the default behavior is to return SQLITE_BUSY. You can - adjust this behavior from C code using the sqlite_busy_handler() or - sqlite_busy_timeout() API functions. See the API documentation - for details.

    - -

    If two or more processes have the same database open and one - process creates a new table or index, the other processes might - not be able to see the new table right away. You might have to - get the other processes to close and reopen their connection to - the database before they will be able to see the new table.

    -} - -faq { - Is SQLite threadsafe? -} { -

    Yes. Sometimes. In order to be thread-safe, SQLite must be compiled - with the THREADSAFE preprocessor macro set to 1. In the default - distribution, the windows binaries are compiled to be threadsafe but - the linux binaries are not. If you want to change this, you'll have to - recompile.

    - -

    "Threadsafe" in the previous paragraph means that two or more threads - can run SQLite at the same time on different "sqlite" structures - returned from separate calls to sqlite_open(). It is never safe - to use the same sqlite structure pointer simultaneously in two - or more threads.

    - -

    Note that if two or more threads have the same database open and one - thread creates a new table or index, the other threads might - not be able to see the new table right away. You might have to - get the other threads to close and reopen their connection to - the database before they will be able to see the new table.

    - -

    Under UNIX, you should not carry an open SQLite database across - a fork() system call into the child process. Problems will result - if you do.

    -} - -faq { - How do I list all tables/indices contained in an SQLite database -} { -

    If you are running the sqlite command-line access program - you can type ".tables" to get a list of all tables. Or you - can type ".schema" to see the complete database schema including - all tables and indices. Either of these commands can be followed by - a LIKE pattern that will restrict the tables that are displayed.

    - -

    From within a C/C++ program (or a script using Tcl/Ruby/Perl/Python - bindings) you can get access to table and index names by doing a SELECT - on a special table named "SQLITE_MASTER". Every SQLite database - has an SQLITE_MASTER table that defines the schema for the database. - The SQLITE_MASTER table looks like this:

    -
    -CREATE TABLE sqlite_master (
    -  type TEXT,
    -  name TEXT,
    -  tbl_name TEXT,
    -  rootpage INTEGER,
    -  sql TEXT
    -);
    -
    -

    For tables, the type field will always be 'table' and the - name field will be the name of the table. So to get a list of - all tables in the database, use the following SELECT command:

    -
    -SELECT name FROM sqlite_master
    -WHERE type='table'
    -ORDER BY name;
    -
    -

    For indices, type is equal to 'index', name is the - name of the index and tbl_name is the name of the table to which - the index belongs. For both tables and indices, the sql field is - the text of the original CREATE TABLE or CREATE INDEX statement that - created the table or index. For automatically created indices (used - to implement the PRIMARY KEY or UNIQUE constraints) the sql field - is NULL.

    - -

    The SQLITE_MASTER table is read-only. You cannot change this table - using UPDATE, INSERT, or DELETE. The table is automatically updated by - CREATE TABLE, CREATE INDEX, DROP TABLE, and DROP INDEX commands.

    - -

    Temporary tables do not appear in the SQLITE_MASTER table. Temporary - tables and their indices and triggers occur in another special table - named SQLITE_TEMP_MASTER. SQLITE_TEMP_MASTER works just like SQLITE_MASTER - except that it is only visible to the application that created the - temporary tables. To get a list of all tables, both permanent and - temporary, one can use a command similar to the following: -

    -SELECT name FROM 
    -   (SELECT * FROM sqlite_master UNION ALL
    -    SELECT * FROM sqlite_temp_master)
    -WHERE type='table'
    -ORDER BY name
    -
    -} - -faq { - Are there any known size limits to SQLite databases? -} { -

    As of version 2.7.4, - SQLite can handle databases up to 241 bytes (2 terabytes) - in size on both Windows and Unix. Older version of SQLite - were limited to databases of 231 bytes (2 gigabytes).

    - -

    SQLite version 2.8 limits the amount of data in one row to - 1 megabyte. SQLite version 3.0 has no limit on the amount of - data that can be stored in a single row. -

    - -

    The names of tables, indices, view, triggers, and columns can be - as long as desired. However, the names of SQL functions (as created - by the sqlite_create_function() API) - may not exceed 255 characters in length.

    -} - -faq { - What is the maximum size of a VARCHAR in SQLite? -} { -

    SQLite does not enforce datatype constraints. - A VARCHAR column can hold as much data as you care to put in it.

    -} - -faq { - Does SQLite support a BLOB type? -} { -

    SQLite version 3.0 lets you puts BLOB data into any column, even - columns that are declared to hold some other type.

    - -

    SQLite version 2.8 will store any text data without embedded - '\000' characters. If you need to store BLOB data in SQLite version - 2.8 you'll want to encode that data first. - There is a source file named - "src/encode.c" in the SQLite version 2.8 distribution that contains - implementations of functions named "sqlite_encode_binary() - and sqlite_decode_binary() that can be used for converting - binary data to ASCII and back again, if you like.

    - - -} - -faq { - How do I add or delete columns from an existing table in SQLite. -} { -

    SQLite does yes not support the "ALTER TABLE" SQL command. If you - what to change the structure of a table, you have to recreate the - table. You can save existing data to a temporary table, drop the - old table, create the new table, then copy the data back in from - the temporary table.

    - -

    For example, suppose you have a table named "t1" with columns - names "a", "b", and "c" and that you want to delete column "c" from - this table. The following steps illustrate how this could be done: -

    - -
    -BEGIN TRANSACTION;
    -CREATE TEMPORARY TABLE t1_backup(a,b);
    -INSERT INTO t1_backup SELECT a,b FROM t1;
    -DROP TABLE t1;
    -CREATE TABLE t1(a,b);
    -INSERT INTO t1 SELECT a,b FROM t1_backup;
    -DROP TABLE t1_backup;
    -COMMIT;
    -
    -} - -faq { - I deleted a lot of data but the database file did not get any - smaller. Is this a bug? -} { -

    No. When you delete information from an SQLite database, the - unused disk space is added to an internal "free-list" and is reused - the next time you insert data. The disk space is not lost. But - neither is it returned to the operating system.

    - -

    If you delete a lot of data and want to shrink the database file, - run the VACUUM command (version 2.8.1 and later). VACUUM will reconstruct - the database from scratch. This will leave the database with an empty - free-list and a file that is minimal in size. Note, however, that the - VACUUM can take some time to run (around a half second per megabyte - on the Linux box where SQLite is developed) and it can use up to twice - as much temporary disk space as the original file while it is running. -

    - -

    As of SQLite version 3.1, an alternative to using the VACUUM command - is auto-vacuum mode, enabled using the - auto_vacuum pragma.

    -} - -faq { - Can I use SQLite in my commercial product without paying royalties? -} { -

    Yes. SQLite is in the public domain. No claim of ownership is made - to any part of the code. You can do anything you want with it.

    -} - -faq { - How do I use a string literal that contains an embedded single-quote (') - character? -} { -

    The SQL standard specifies that single-quotes in strings are escaped - by putting two single quotes in a row. SQL works like the Pascal programming - language in the regard. SQLite follows this standard. Example: -

    - -
    -    INSERT INTO xyz VALUES('5 O''clock');
    -  
    -} - -faq {What is an SQLITE_SCHEMA error, and why am I getting one?} { -

    In version 3 of SQLite, an SQLITE_SCHEMA error is returned when a - prepared SQL statement is no longer valid and cannot be executed. - When this occurs, the statement must be recompiled from SQL using - the sqlite3_prepare() API. In SQLite 3, an SQLITE_SCHEMA error can - only occur when using the sqlite3_prepare()/sqlite3_step()/sqlite3_finalize() - API to execute SQL, not when using the sqlite3_exec(). This was not - the case in version 2.

    - -

    The most common reason for a prepared statement to become invalid - is that the schema of the database was modified after the SQL was - prepared (possibly by another process). The other reasons this can - happen are:

    -
      -
    • A database was DETACHed. -
    • A user-function definition was deleted or changed. -
    • A collation sequence definition was deleted or changed. -
    • The authorization function was changed. -
    - -

    In all cases, the solution is to recompile the statement from SQL - and attempt to execute it again. Because a prepared statement can be - invalidated by another process changing the database schema, all code - that uses the sqlite3_prepare()/sqlite3_step()/sqlite3_finalize() - API should be prepared to handle SQLITE_SCHEMA errors. An example - of one approach to this follows:

    - -
    -
    -    int rc;
    -    sqlite3_stmt *pStmt;
    -    char zSql[] = "SELECT .....";
    -
    -    do {
    -      /* Compile the statement from SQL. Assume success. */
    -      sqlite3_prepare(pDb, zSql, -1, &pStmt, 0);
    -
    -      while( SQLITE_ROW==sqlite3_step(pStmt) ){
    -        /* Do something with the row of available data */
    -      }
    -
    -      /* Finalize the statement. If an SQLITE_SCHEMA error has
    -      ** occured, then the above call to sqlite3_step() will have
    -      ** returned SQLITE_ERROR. sqlite3_finalize() will return
    -      ** SQLITE_SCHEMA. In this case the loop will execute again.
    -      */
    -      rc = sqlite3_finalize(pStmt);
    -    } while( rc==SQLITE_SCHEMA );
    -    
    -  
    -} - -# End of questions and answers. -############# - -puts {

    Frequently Asked Questions

    } - -# puts {
    } -# for {set i 1} {$i<$cnt} {incr i} { -# puts "
    ($i)
    " -# puts "
    [lindex $faq($i) 0]
    " -# } -# puts {
    } -puts {
      } -for {set i 1} {$i<$cnt} {incr i} { - puts "
    1. [lindex $faq($i) 0]
    2. " -} -puts {
    } - -for {set i 1} {$i<$cnt} {incr i} { - puts "
    " - puts "

    ($i) [lindex $faq($i) 0]

    \n" - puts "
    [lindex $faq($i) 1]
    \n" -} - -puts {} -footer $rcsid diff --git a/sqlite/www/index.tcl b/sqlite/www/index.tcl deleted file mode 100644 index 0d04051..0000000 --- a/sqlite/www/index.tcl +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/tclsh -source common.tcl -header {SQLite home page} -puts { - - - - -
    -

    About SQLite

    -

    -SQLite is a small C library that implements a -self-contained, embeddable, -zero-configuration SQL database engine. -Features include: -

    - -

      -
    • Transactions are atomic, consistent, isolated, and durable (ACID) - even after system crashes and power failures. -
    • Zero-configuration - no setup or administration needed.
    • -
    • Implements most of SQL92. - (Features not supported)
    • -
    • A complete database is stored in a single disk file.
    • -
    • Database files can be freely shared between machines with - different byte orders.
    • -
    • Supports databases up to 2 terabytes - (241 bytes) in size.
    • -
    • Sizes of strings and BLOBs limited only by available memory.
    • -
    • Small code footprint: less than 30K lines of C code, - less than 250KB code space (gcc on i486)
    • -
    • Faster than popular client/server database - engines for most common operations.
    • -
    • Simple, easy to use API.
    • -
    • TCL bindings included. - Bindings for many other languages - - available separately.
    • -
    • Well-commented source code with over 95% test coverage.
    • -
    • Self-contained: no external dependencies.
    • -
    • Sources are in the public domain. - Use for any purpose.
    • -
    -

    - -

    -The SQLite distribution comes with a standalone command-line -access program (sqlite) that can -be used to administer an SQLite database and which serves as -an example of how to use the SQLite library. -

    - -
    -

    News

    -} - -proc newsitem {date title text} { - puts "

    $date - $title

    " - regsub -all "\n( *\n)+" $text "

    \n\n

    " txt - puts "

    $txt

    " - puts "
    " -} - -newsitem {2005-Feb-15} {Versions 2.8.16 and 3.1.2 Released} { - A critical bug in the VACUUM command that can lead to database - corruption has been fixed in both the 2.x branch and the main - 3.x line. This bug has existed in all prior versions of SQLite. - Even though it is unlikely you will ever encounter this bug, - it is suggested that all users upgrade. See - - ticket #1116. for additional information. - - Version 3.1.2 is also the first stable release of the 3.1 - series. SQLite 3.1 features added support for correlated - subqueries, autovacuum, autoincrement, ALTER TABLE, and - other enhancements. See the - release notes - for version 3.1.0 for a detailed description of the - changes available in the 3.1 series. -} - -newsitem {2004-Nov-09} {SQLite at the 2004 International PHP Conference} { - There was a talk on the architecture of SQLite and how to optimize - SQLite queries at the 2004 International PHP Conference in Frankfurt, - Germany. - - Slides from that talk are available. -} - - -newsitem {2004-Oct-10} {SQLite at the 11th -Annual Tcl/Tk Conference} { - There will be a talk on the use of SQLite in Tcl/Tk at the - 11th Tcl/Tk Conference this week in - New Orleans. Visit - http://www.tcl.tk/ for details. - - Slides from the talk are available. -} - - -puts { -

    Old news...

    -
    -} -footer {$Id: index.tcl,v 1.106 2005/02/15 12:51:16 drh Exp $} diff --git a/sqlite/www/lang.tcl b/sqlite/www/lang.tcl deleted file mode 100644 index d7d4e08..0000000 --- a/sqlite/www/lang.tcl +++ /dev/null @@ -1,1804 +0,0 @@ -# -# Run this Tcl script to generate the lang-*.html files. -# -set rcsid {$Id: lang.tcl,v 1.82 2005/01/24 23:27:32 danielk1977 Exp $} -source common.tcl - -if {[llength $argv]>0} { - set outputdir [lindex $argv 0] -} else { - set outputdir "" -} - -header {Query Language Understood by SQLite} -puts { -

    SQL As Understood By SQLite

    - -

    The SQLite library understands most of the standard SQL -language. But it does omit some features -while at the same time -adding a few features of its own. This document attempts to -describe precisely what parts of the SQL language SQLite does -and does not support. A list of keywords is -also provided.

    - -

    In all of the syntax diagrams that follow, literal text is shown in -bold blue. Non-terminal symbols are shown in italic red. Operators -that are part of the syntactic markup itself are shown in black roman.

    - -

    This document is just an overview of the SQL syntax implemented -by SQLite. Many low-level productions are omitted. For detailed information -on the language that SQLite understands, refer to the source code and -the grammar file "parse.y".

    - - -

    SQLite implements the follow syntax:

    -

      -} - -proc slink {label} { - if {[string match *.html $label]} { - return $label - } - if {[string length $::outputdir]==0} { - return #$label - } else { - return lang_$label.html - } -} - -foreach {section} [lsort -index 0 -dictionary { - {{CREATE TABLE} createtable} - {{CREATE INDEX} createindex} - {VACUUM vacuum} - {{DROP TABLE} droptable} - {{DROP INDEX} dropindex} - {INSERT insert} - {REPLACE replace} - {DELETE delete} - {UPDATE update} - {SELECT select} - {comment comment} - {COPY copy} - {EXPLAIN explain} - {expression expr} - {{BEGIN TRANSACTION} transaction} - {{COMMIT TRANSACTION} transaction} - {{END TRANSACTION} transaction} - {{ROLLBACK TRANSACTION} transaction} - {PRAGMA pragma.html} - {{ON CONFLICT clause} conflict} - {{CREATE VIEW} createview} - {{DROP VIEW} dropview} - {{CREATE TRIGGER} createtrigger} - {{DROP TRIGGER} droptrigger} - {{ATTACH DATABASE} attach} - {{DETACH DATABASE} detach} - {REINDEX reindex} - {{ALTER TABLE} altertable} -}] { - foreach {s_title s_tag} $section {} - puts "
    • $s_title
    • " -} -puts {

    - -

    Details on the implementation of each command are provided in -the sequel.

    -} - -proc Operator {name} { - return "$name" -} -proc Nonterminal {name} { - return "$name" -} -proc Keyword {name} { - return "$name" -} -proc Example {text} { - puts "
    $text
    " -} - -proc Section {name label} { - global outputdir - - if {[string length $outputdir]!=0} { - if {[llength [info commands puts_standard]]>0} { - footer $::rcsid - } - - if {[string length $label]>0} { - rename puts puts_standard - proc puts {str} { - regsub -all {href="#([a-z]+)"} $str {href="lang_\1.html"} str - puts_standard $::section_file $str - } - rename footer footer_standard - proc footer {id} { - footer_standard $id - rename footer "" - rename puts "" - rename puts_standard puts - rename footer_standard footer - } - set ::section_file [open [file join $outputdir lang_$label.html] w] - header "Query Language Understood by SQLite: $name" - puts "

    SQL As Understood By SQLite

    " - puts "\[Contents\]" - puts "

    $name

    " - return - } - } - puts "\n
    " - if {$label!=""} { - puts "" - } - puts "

    $name

    \n" -} - -Section {ALTER TABLE} altertable - -Syntax {sql-statement} { -ALTER TABLE [ .] RENAME TO -} - -puts { -

    SQLite's version of the ALTER TABLE command allows the user to -rename an existing table. The table identified by -[database-name.]table-name is renamed to -new-table-name. This command cannot be used to move a -table between attached databases, only to rename a table within -the same database.

    - -

    If the table being renamed has triggers or indices, then these remain -attached to the table after it has been renamed. However, if there are -any view definitions, or statements executed by triggers that refer to -the table being renamed, these are not automatically modified to use the new -table name. If this is required, the triggers or view definitions must be -dropped and recreated to use the new table name by hand. -

    -} - -Section {ATTACH DATABASE} attach - -Syntax {sql-statement} { -ATTACH [DATABASE] AS -} - -puts { -

    The ATTACH DATABASE statement adds a preexisting database -file to the current database connection. If the filename contains -punctuation characters it must be quoted. The names 'main' and -'temp' refer to the main database and the database used for -temporary tables. These cannot be detached. Attached databases -are removed using the DETACH DATABASE -statement.

    - -

    You can read from and write to an attached database and you -can modify the schema of the attached database. This is a new -feature of SQLite version 3.0. In SQLite 2.8, schema changes -to attached databases were not allowed.

    - -

    You cannot create a new table with the same name as a table in -an attached database, but you can attach a database which contains -tables whose names are duplicates of tables in the main database. It is -also permissible to attach the same database file multiple times.

    - -

    Tables in an attached database can be referred to using the syntax -database-name.table-name. If an attached table doesn't have -a duplicate table name in the main database, it doesn't require a -database name prefix. When a database is attached, all of its -tables which don't have duplicate names become the 'default' table -of that name. Any tables of that name attached afterwards require the table -prefix. If the 'default' table of a given name is detached, then -the last table of that name attached becomes the new default.

    - -

    -Transactions involving multiple attached databases are atomic, -assuming that the main database is not ":memory:". If the main -database is ":memory:" then -transactions continue to be atomic within each individual -database file. But if the host computer crashes in the middle -of a COMMIT where two or more database files are updated, -some of those files might get the changes where others -might not. -Atomic commit of attached databases is a new feature of SQLite version 3.0. -In SQLite version 2.8, all commits to attached databases behaved as if -the main database were ":memory:". -

    - -

    There is a compile-time limit of 10 attached database files.

    -} - - -Section {BEGIN TRANSACTION} transaction - -Syntax {sql-statement} { -BEGIN [ DEFERRED | IMMEDIATE | EXCLUSIVE ] [TRANSACTION []] -} -Syntax {sql-statement} { -END [TRANSACTION []] -} -Syntax {sql-statement} { -COMMIT [TRANSACTION []] -} -Syntax {sql-statement} { -ROLLBACK [TRANSACTION []] -} - -puts { -

    Beginning in version 2.0, SQLite supports transactions with -rollback and atomic commit.

    - -

    The optional transaction name is ignored. SQLite currently -does not allow nested transactions.

    - -

    -No changes can be made to the database except within a transaction. -Any command that changes the database (basically, any SQL command -other than SELECT) will automatically start a transaction if -one is not already in effect. Automatically started transactions -are committed at the conclusion of the command. -

    - -

    -Transactions can be started manually using the BEGIN -command. Such transactions usually persist until the next -COMMIT or ROLLBACK command. But a transaction will also -ROLLBACK if the database is closed or if an error occurs -and the ROLLBACK conflict resolution algorithm is specified. -See the documentation on the ON CONFLICT -clause for additional information about the ROLLBACK -conflict resolution algorithm. -

    - -

    -In SQLite version 3.0.8 and later, transactions can be deferred, -immediate, or exclusive. Deferred means that no locks are acquired -on the database until the database is first accessed. Thus with a -deferred transaction, the BEGIN statement itself does nothing. Locks -are not acquired until the first read or write operation. The first read -operation against a database creates a SHARED lock and the first -write operation creates a RESERVED lock. Because the acquisition of -locks is deferred until they are needed, it is possible that another -thread or process could create a separate transaction and write to -the database after the BEGIN on the current thread has executed. -If the transaction is immediate, then RESERVED locks -are acquired on all databases as soon as the BEGIN command is -executed, without waiting for the -database to be used. After a BEGIN IMMEDIATE, you are guaranteed that -no other thread or process will be able to write to the database or -do a BEGIN IMMEDIATE or BEGIN EXCLUSIVE. Other processes can continue -to read from the database, however. An exclusive transaction causes -EXCLUSIVE locks to be acquired on all databases. After a BEGIN -EXCLUSIVE, you are guaranteed that no other thread or process will -be able to read or write the database until the transaction is -complete. -

    - -

    -A description of the meaning of SHARED, RESERVED, and EXCLUSIVE locks -is available separately. -

    - -

    -The default behavior for SQLite version 3.0.8 is a -deferred transaction. For SQLite version 3.0.0 through 3.0.7, -deferred is the only kind of transaction available. For SQLite -version 2.8 and earlier, all transactions are exclusive. -

    - -

    -The COMMIT command does not actually perform a commit until all -pending SQL commands finish. Thus if two or more SELECT statements -are in the middle of processing and a COMMIT is executed, the commit -will not actually occur until all SELECT statements finish. -

    - -

    -An attempt to execute COMMIT might result in an SQLITE_BUSY return code. -This indicates that another thread or process had a read lock on the database -that prevented the database from being updated. When COMMIT fails in this -way, the transaction remains active and the COMMIT can be retried later -after the reader has had a chance to clear. -

    -} - - -Section comment comment - -Syntax {comment} { | -} {SQL-comment} {-- -} {C-comment} {/STAR [STAR/] -} - -puts { -

    Comments aren't SQL commands, but can occur in SQL queries. They are -treated as whitespace by the parser. They can begin anywhere whitespace -can be found, including inside expressions that span multiple lines. -

    - -

    SQL comments only extend to the end of the current line.

    - -

    C comments can span any number of lines. If there is no terminating -delimiter, they extend to the end of the input. This is not treated as -an error. A new SQL statement can begin on a line after a multiline -comment ends. C comments can be embedded anywhere whitespace can occur, -including inside expressions, and in the middle of other SQL statements. -C comments do not nest. SQL comments inside a C comment will be ignored. -

    -} - - -Section COPY copy - -Syntax {sql-statement} { -COPY [ OR ] [ .] FROM -[ USING DELIMITERS ] -} - -puts { -

    The COPY command is available in SQLite version 2.8 and earlier. -The COPY command has been removed from SQLite version 3.0 due to -complications in trying to support it in a mixed UTF-8/16 environment. -In version 3.0, the command-line shell -contains a new command .import that can be used as a substitute -for COPY. -

    - -

    The COPY command is an extension used to load large amounts of -data into a table. It is modeled after a similar command found -in PostgreSQL. In fact, the SQLite COPY command is specifically -designed to be able to read the output of the PostgreSQL dump -utility pg_dump so that data can be easily transferred from -PostgreSQL into SQLite.

    - -

    The table-name is the name of an existing table which is to -be filled with data. The filename is a string or identifier that -names a file from which data will be read. The filename can be -the STDIN to read data from standard input.

    - -

    Each line of the input file is converted into a single record -in the table. Columns are separated by tabs. If a tab occurs as -data within a column, then that tab is preceded by a baskslash "\" -character. A baskslash in the data appears as two backslashes in -a row. The optional USING DELIMITERS clause can specify a delimiter -other than tab.

    - -

    If a column consists of the character "\N", that column is filled -with the value NULL.

    - -

    The optional conflict-clause allows the specification of an alternative -constraint conflict resolution algorithm to use for this one command. -See the section titled -ON CONFLICT for additional information.

    - -

    When the input data source is STDIN, the input can be terminated -by a line that contains only a baskslash and a dot:} -puts "\"[Operator \\.]\".

    " - - -Section {CREATE INDEX} createindex - -Syntax {sql-statement} { -CREATE [UNIQUE] INDEX -ON [ .] ( [, ]* ) -[ ON CONFLICT ] -} {column-name} { - [ COLLATE ] [ ASC | DESC ] -} - -puts { -

    The CREATE INDEX command consists of the keywords "CREATE INDEX" followed -by the name of the new index, the keyword "ON", the name of a previously -created table that is to be indexed, and a parenthesized list of names of -columns in the table that are used for the index key. -Each column name can be followed by one of the "ASC" or "DESC" keywords -to indicate sort order, but the sort order is ignored in the current -implementation. Sorting is always done in ascending order.

    - -

    The COLLATE clause following each column name defines a collating -sequence used for text entires in that column. The default collating -sequence is the collating sequence defined for that column in the -CREATE TABLE statement. Or if no collating sequence is otherwise defined, -the built-in BINARY collating sequence is used.

    - -

    There are no arbitrary limits on the number of indices that can be -attached to a single table, nor on the number of columns in an index.

    - -

    If the UNIQUE keyword appears between CREATE and INDEX then duplicate -index entries are not allowed. Any attempt to insert a duplicate entry -will result in an error.

    - -

    The optional conflict-clause allows the specification of an alternative -default constraint conflict resolution algorithm for this index. -This only makes sense if the UNIQUE keyword is used since otherwise -there are not constraints on the index. The default algorithm is -ABORT. If a COPY, INSERT, or UPDATE statement specifies a particular -conflict resolution algorithm, that algorithm is used in place of -the default algorithm specified here. -See the section titled -ON CONFLICT for additional information.

    - -

    The exact text -of each CREATE INDEX statement is stored in the sqlite_master -or sqlite_temp_master table, depending on whether the table -being indexed is temporary. Every time the database is opened, -all CREATE INDEX statements -are read from the sqlite_master table and used to regenerate -SQLite's internal representation of the index layout.

    - -

    Indexes are removed with the DROP INDEX -command.

    -} - - -Section {CREATE TABLE} {createtable} - -Syntax {sql-command} { -CREATE [TEMP | TEMPORARY] TABLE ( - [, ]* - [, ]* -) -} {sql-command} { -CREATE [TEMP | TEMPORARY] TABLE [.] AS -} {column-def} { - [] [[CONSTRAINT ] ]* -} {type} { - | - ( ) | - ( , ) -} {column-constraint} { -NOT NULL [ ] | -PRIMARY KEY [] [ ] [AUTOINCREMENT] | -UNIQUE [ ] | -CHECK ( ) [ ] | -DEFAULT | -COLLATE -} {constraint} { -PRIMARY KEY ( ) [ ] | -UNIQUE ( ) [ ] | -CHECK ( ) [ ] -} {conflict-clause} { -ON CONFLICT -} - -puts { -

    A CREATE TABLE statement is basically the keywords "CREATE TABLE" -followed by the name of a new table and a parenthesized list of column -definitions and constraints. The table name can be either an identifier -or a string. Tables names that begin with "sqlite_" are reserved -for use by the engine.

    - -

    Each column definition is the name of the column followed by the -datatype for that column, then one or more optional column constraints. -The datatype for the column does not restrict what data may be put -in that column. -See Datatypes In SQLite Version 3 for -additional information. -The UNIQUE constraint causes an index to be created on the specified -columns. This index must contain unique keys. -The COLLATE clause specifies what text -collating function to use when comparing text entries for the column. -The built-in BINARY collating function is used by default. -

    -The DEFAULT constraint specifies a default value to use when doing an INSERT. -The value may be NULL, a string constant or a number. Starting with version -3.1.0, the default value may also be one of the special case-independant -keywords CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP. If the value is -NULL, a string constant or number, it is literally inserted into the column -whenever an INSERT statement that does not specify a value for the column is -executed. If the value is CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP, then -the current UTC date and/or time is inserted into the columns. For -CURRENT_TIME, the format is HH:MM:SS. For CURRENT_DATE, YYYY-MM-DD. The format -for CURRENT_TIMESTAMP is "YYYY-MM-DD HH:MM:SS". -

    - -

    Specifying a PRIMARY KEY normally just creates a UNIQUE index -on the corresponding columns. However, if primary key is on a single column -that has datatype INTEGER, then that column is used internally -as the actual key of the B-Tree for the table. This means that the column -may only hold unique integer values. (Except for this one case, -SQLite ignores the datatype specification of columns and allows -any kind of data to be put in a column regardless of its declared -datatype.) If a table does not have an INTEGER PRIMARY KEY column, -then the B-Tree key will be a automatically generated integer. The -B-Tree key for a row can always be accessed using one of the -special names "ROWID", "OID", or "_ROWID_". -This is true regardless of whether or not there is an INTEGER -PRIMARY KEY. An INTEGER PRIMARY KEY column man also include the -keyword AUTOINCREMENT. The AUTOINCREMENT keyword modified the way -that B-Tree keys are automatically generated. Additional detail -on automatic B-Tree key generation is available -separately.

    - -

    If the "TEMP" or "TEMPORARY" keyword occurs in between "CREATE" -and "TABLE" then the table that is created is only visible to the -process that opened the database and is automatically deleted when -the database is closed. Any indices created on a temporary table -are also temporary. Temporary tables and indices are stored in a -separate file distinct from the main database file.

    - -

    If a is specified, then the table is created in -the named database. It is an error to specify both a -and the TEMP keyword, unless the is "temp". If no -database name is specified, and the TEMP keyword is not present, -the table is created in the main database.

    - -

    The optional conflict-clause following each constraint -allows the specification of an alternative default -constraint conflict resolution algorithm for that constraint. -The default is abort ABORT. Different constraints within the same -table may have different default conflict resolution algorithms. -If an COPY, INSERT, or UPDATE command specifies a different conflict -resolution algorithm, then that algorithm is used in place of the -default algorithm specified in the CREATE TABLE statement. -See the section titled -ON CONFLICT for additional information.

    - -

    CHECK constraints are ignored in the current implementation. -Support for CHECK constraints may be added in the future. As of -version 2.3.0, NOT NULL, PRIMARY KEY, and UNIQUE constraints all -work.

    - -

    There are no arbitrary limits on the number -of columns or on the number of constraints in a table. -The total amount of data in a single row is limited to about -1 megabytes in version 2.8. In version 3.0 there is no arbitrary -limit on the amount of data in a row.

    - - -

    The CREATE TABLE AS form defines the table to be -the result set of a query. The names of the table columns are -the names of the columns in the result.

    - -

    The exact text -of each CREATE TABLE statement is stored in the sqlite_master -table. Every time the database is opened, all CREATE TABLE statements -are read from the sqlite_master table and used to regenerate -SQLite's internal representation of the table layout. -If the original command was a CREATE TABLE AS then then an equivalent -CREATE TABLE statement is synthesized and store in sqlite_master -in place of the original command. -The text of CREATE TEMPORARY TABLE statements are stored in the -sqlite_temp_master table. -

    - -

    Tables are removed using the DROP TABLE -statement.

    -} - - -Section {CREATE TRIGGER} createtrigger - -Syntax {sql-statement} { -CREATE [TEMP | TEMPORARY] TRIGGER [ BEFORE | AFTER ] - ON [ .] - -} - -Syntax {sql-statement} { -CREATE [TEMP | TEMPORARY] TRIGGER INSTEAD OF - ON [ .] - -} - -Syntax {database-event} { -DELETE | -INSERT | -UPDATE | -UPDATE OF -} - -Syntax {trigger-action} { -[ FOR EACH ROW | FOR EACH STATEMENT ] [ WHEN ] -BEGIN - ; [ ; ]* -END -} - -Syntax {trigger-step} { - | | - | -} - -puts { -

    The CREATE TRIGGER statement is used to add triggers to the -database schema. Triggers are database operations (the trigger-action) -that are automatically performed when a specified database event (the -database-event) occurs.

    - -

    A trigger may be specified to fire whenever a DELETE, INSERT or UPDATE of a -particular database table occurs, or whenever an UPDATE of one or more -specified columns of a table are updated.

    - -

    At this time SQLite supports only FOR EACH ROW triggers, not FOR EACH -STATEMENT triggers. Hence explicitly specifying FOR EACH ROW is optional. FOR -EACH ROW implies that the SQL statements specified as trigger-steps -may be executed (depending on the WHEN clause) for each database row being -inserted, updated or deleted by the statement causing the trigger to fire.

    - -

    Both the WHEN clause and the trigger-steps may access elements of -the row being inserted, deleted or updated using references of the form -"NEW.column-name" and "OLD.column-name", where -column-name is the name of a column from the table that the trigger -is associated with. OLD and NEW references may only be used in triggers on -trigger-events for which they are relevant, as follows:

    - - - - - - - - - - - - - - -
    INSERTNEW references are valid
    UPDATENEW and OLD references are valid
    DELETEOLD references are valid
    -

    - -

    If a WHEN clause is supplied, the SQL statements specified as trigger-steps are only executed for rows for which the WHEN clause is true. If no WHEN clause is supplied, the SQL statements are executed for all rows.

    - -

    The specified trigger-time determines when the trigger-steps -will be executed relative to the insertion, modification or removal of the -associated row.

    - -

    An ON CONFLICT clause may be specified as part of an UPDATE or INSERT -trigger-step. However if an ON CONFLICT clause is specified as part of -the statement causing the trigger to fire, then this conflict handling -policy is used instead.

    - -

    Triggers are automatically dropped when the table that they are -associated with is dropped.

    - -

    Triggers may be created on views, as well as ordinary tables, by specifying -INSTEAD OF in the CREATE TRIGGER statement. If one or more ON INSERT, ON DELETE -or ON UPDATE triggers are defined on a view, then it is not an error to execute -an INSERT, DELETE or UPDATE statement on the view, respectively. Thereafter, -executing an INSERT, DELETE or UPDATE on the view causes the associated - triggers to fire. The real tables underlying the view are not modified - (except possibly explicitly, by a trigger program).

    - -

    Example:

    - -

    Assuming that customer records are stored in the "customers" table, and -that order records are stored in the "orders" table, the following trigger -ensures that all associated orders are redirected when a customer changes -his or her address:

    -} -Example { -CREATE TRIGGER update_customer_address UPDATE OF address ON customers - BEGIN - UPDATE orders SET address = new.address WHERE customer_name = old.name; - END; -} -puts { -

    With this trigger installed, executing the statement:

    -} - -Example { -UPDATE customers SET address = '1 Main St.' WHERE name = 'Jack Jones'; -} -puts { -

    causes the following to be automatically executed:

    -} -Example { -UPDATE orders SET address = '1 Main St.' WHERE customer_name = 'Jack Jones'; -} - -puts { -

    Note that currently, triggers may behave oddly when created on tables - with INTEGER PRIMARY KEY fields. If a BEFORE trigger program modifies the - INTEGER PRIMARY KEY field of a row that will be subsequently updated by the - statement that causes the trigger to fire, then the update may not occur. - The workaround is to declare the table with a PRIMARY KEY column instead - of an INTEGER PRIMARY KEY column.

    -} - -puts { -

    A special SQL function RAISE() may be used within a trigger-program, with the following syntax

    -} -Syntax {raise-function} { -RAISE ( ABORT, ) | -RAISE ( FAIL, ) | -RAISE ( ROLLBACK, ) | -RAISE ( IGNORE ) -} -puts { -

    When one of the first three forms is called during trigger-program execution, the specified ON CONFLICT processing is performed (either ABORT, FAIL or - ROLLBACK) and the current query terminates. An error code of SQLITE_CONSTRAINT is returned to the user, along with the specified error message.

    - -

    When RAISE(IGNORE) is called, the remainder of the current trigger program, -the statement that caused the trigger program to execute and any subsequent - trigger programs that would of been executed are abandoned. No database - changes are rolled back. If the statement that caused the trigger program - to execute is itself part of a trigger program, then that trigger program - resumes execution at the beginning of the next step. -

    - -

    Triggers are removed using the DROP TRIGGER -statement. Non-temporary triggers cannot be added on a table in an -attached database.

    -} - - -Section {CREATE VIEW} {createview} - -Syntax {sql-command} { -CREATE [TEMP | TEMPORARY] VIEW [.] AS -} - -puts { -

    The CREATE VIEW command assigns a name to a pre-packaged -SELECT -statement. Once the view is created, it can be used in the FROM clause -of another SELECT in place of a table name. -

    - -

    If the "TEMP" or "TEMPORARY" keyword occurs in between "CREATE" -and "TABLE" then the table that is created is only visible to the -process that opened the database and is automatically deleted when -the database is closed.

    - -

    If a is specified, then the view is created in -the named database. It is an error to specify both a -and the TEMP keyword, unless the is "temp". If no -database name is specified, and the TEMP keyword is not present, -the table is created in the main database.

    - -

    You cannot COPY, DELETE, INSERT or UPDATE a view. Views are read-only -in SQLite. However, in many cases you can use a -TRIGGER on the view to accomplish the same thing. Views are removed -with the DROP VIEW -command. Non-temporary views cannot be created on tables in an attached -database.

    -} - - -Section DELETE delete - -Syntax {sql-statement} { -DELETE FROM [ .] [WHERE ] -} - -puts { -

    The DELETE command is used to remove records from a table. -The command consists of the "DELETE FROM" keywords followed by -the name of the table from which records are to be removed. -

    - -

    Without a WHERE clause, all rows of the table are removed. -If a WHERE clause is supplied, then only those rows that match -the expression are removed.

    -} - - -Section {DETACH DATABASE} detach - -Syntax {sql-command} { -DETACH [DATABASE] -} - -puts { -

    This statement detaches an additional database connection previously -attached using the ATTACH DATABASE statement. It -is possible to have the same database file attached multiple times using -different names, and detaching one connection to a file will leave the -others intact.

    - -

    This statement will fail if SQLite is in the middle of a transaction.

    -} - - -Section {DROP INDEX} dropindex - -Syntax {sql-command} { -DROP INDEX [ .] -} - -puts { -

    The DROP INDEX statement removes an index added -with the -CREATE INDEX statement. The index named is completely removed from -the disk. The only way to recover the index is to reenter the -appropriate CREATE INDEX command.

    - -

    The DROP INDEX statement does not reduce the size of the database -file. Empty space in the database is retained for later INSERTs. To -remove free space in the database, use the VACUUM -command.

    -} - - -Section {DROP TABLE} droptable - -Syntax {sql-command} { -DROP TABLE [.] -} - -puts { -

    The DROP TABLE statement removes a table added with the CREATE TABLE statement. The name specified is the -table name. It is completely removed from the database schema and the -disk file. The table can not be recovered. All indices associated -with the table are also deleted. Non-temporary tables in an attached -database cannot be dropped.

    - -

    The DROP TABLE statement does not reduce the size of the database -file. Empty space in the database is retained for later INSERTs. To -remove free space in the database, use the VACUUM -command.

    -} - - -Section {DROP TRIGGER} droptrigger -Syntax {sql-statement} { -DROP TRIGGER [ .] -} -puts { -

    The DROP TRIGGER statement removes a trigger created by the -CREATE TRIGGER statement. The trigger is -deleted from the database schema. Note that triggers are automatically -dropped when the associated table is dropped. Non-temporary triggers -cannot be dropped on attached tables.

    -} - - -Section {DROP VIEW} dropview - -Syntax {sql-command} { -DROP VIEW -} - -puts { -

    The DROP VIEW statement removes a view created by the CREATE VIEW statement. The name specified is the -view name. It is removed from the database schema, but no actual data -in the underlying base tables is modified. Non-temporary views in -attached databases cannot be dropped.

    -} - - -Section EXPLAIN explain - -Syntax {sql-statement} { -EXPLAIN -} - -puts { -

    The EXPLAIN command modifier is a non-standard extension. The -idea comes from a similar command found in PostgreSQL, but the operation -is completely different.

    - -

    If the EXPLAIN keyword appears before any other SQLite SQL command -then instead of actually executing the command, the SQLite library will -report back the sequence of virtual machine instructions it would have -used to execute the command had the EXPLAIN keyword not been present. -For additional information about virtual machine instructions see -the architecture description or the documentation -on available opcodes for the virtual machine.

    -} - - -Section expression expr - -Syntax {expr} { - | - [ESCAPE ] | - | - | -( ) | - | - . | - . . | - | - ( | STAR ) | - ISNULL | - NOTNULL | - [NOT] BETWEEN AND | - [NOT] IN ( ) | - [NOT] IN ( ) | - [NOT] IN [ .] | -( ) | -CASE [] LP WHEN THEN RPPLUS [ELSE ] END -} {like-op} { -LIKE | NOT LIKE -} {glob-op} { -GLOB | NOT GLOB -} - -puts { -

    This section is different from the others. Most other sections of -this document talks about a particular SQL command. This section does -not talk about a standalone command but about "expressions" which are -subcomponents of most other commands.

    - -

    SQLite understands the following binary operators, in order from -highest to lowest precedence:

    - -
    -||
    -*    /    %
    -+    -
    -<<   >>   &    |
    -<    <=   >    >=
    -=    ==   !=   <>   IN
    -AND   
    -OR
    -
    - -

    Supported unary operators are these:

    - -
    --    +    !    ~
    -
    - -

    Any SQLite value can be used as part of an expression. -For arithmetic operations, integers are treated as integers. -Strings are first converted to real numbers using atof(). -For comparison operators, numbers compare as numbers and strings -compare using the strcmp() function. -Note that there are two variations of the equals and not equals -operators. Equals can be either} -puts "[Operator =] or [Operator ==]. -The non-equals operator can be either -[Operator !=] or [Operator {<>}]. -The [Operator ||] operator is \"concatenate\" - it joins together -the two strings of its operands. -The operator [Operator %] outputs the remainder of its left -operand modulo its right operand.

    " -puts { - - -

    The LIKE operator does a pattern matching comparison. The operand -to the right contains the pattern, the left hand operand contains the -string to match against the pattern. -} -puts "A percent symbol [Operator %] in the pattern matches any -sequence of zero or more characters in the string. An underscore -[Operator _] in the pattern matches any single character in the -string. Any other character matches itself or it's lower/upper case -equivalent (i.e. case-insensitive matching). (A bug: SQLite only -understands upper/lower case for 7-bit Latin characters. Hence the -LIKE operator is case sensitive for 8-bit iso8859 characters or UTF-8 -characters. For example, the expression 'a' LIKE 'A' -is TRUE but 'æ' LIKE 'Æ' is FALSE.).

    " - -puts { -

    If the optional ESCAPE clause is present, then the expression -following the ESCAPE keyword must evaluate to a string consisting of -a single character. This character may be used in the LIKE pattern -to include literal percent or underscore characters. The escape -character followed by a percent symbol, underscore or itself matches a -literal percent symbol, underscore or escape character in the string, -respectively. The infix LIKE operator is implemented by calling the -user function like(X,Y).

    -} - -puts { -

    The LIKE operator does a wildcard comparison. The operand -to the right contains the wildcards.} -puts "A percent symbol [Operator %] in the right operand -matches any sequence of zero or more characters on the left. -An underscore [Operator _] on the right -matches any single character on the left." - -puts { -The LIKE operator is not case sensitive and will match upper case -characters on one side against lower case characters on the other. -(A bug: SQLite only understands upper/lower case for 7-bit Latin -characters. Hence the LIKE operator is case sensitive for 8-bit -iso8859 characters or UTF-8 characters. For example, the expression -'a' LIKE 'A' is TRUE but -'æ' LIKE 'Æ' is FALSE.). The infix LIKE -operator is identical the user function -like(X,Y). -

    - - -

    The GLOB operator is similar to LIKE but uses the Unix -file globbing syntax for its wildcards. Also, GLOB is case -sensitive, unlike LIKE. Both GLOB and LIKE may be preceded by -the NOT keyword to invert the sense of the test. The infix GLOB -operator is identical the user function -glob(X,Y).

    - -

    A column name can be any of the names defined in the CREATE TABLE -statement or one of the following special identifiers: "ROWID", -"OID", or "_ROWID_". -These special identifiers all describe the -unique random integer key (the "row key") associated with every -row of every table. -The special identifiers only refer to the row key if the CREATE TABLE -statement does not define a real column with the same name. Row keys -act like read-only columns. A row key can be used anywhere a regular -column can be used, except that you cannot change the value -of a row key in an UPDATE or INSERT statement. -"SELECT * ..." does not return the row key.

    - -

    SELECT statements can appear in expressions as either the -right-hand operand of the IN operator or as a scalar quantity. -In both cases, the SELECT should have only a single column in its -result. Compound SELECTs (connected with keywords like UNION or -EXCEPT) are allowed. -A SELECT in an expression is evaluated once before any other processing -is performed, so none of the expressions within the select itself can -refer to quantities in the containing expression.

    - -

    When a SELECT is the right operand of the IN operator, the IN -operator returns TRUE if the result of the left operand is any of -the values generated by the select. The IN operator may be preceded -by the NOT keyword to invert the sense of the test.

    - -

    When a SELECT appears within an expression but is not the right -operand of an IN operator, then the first row of the result of the -SELECT becomes the value used in the expression. If the SELECT yields -more than one result row, all rows after the first are ignored. If -the SELECT yields no rows, then the value of the SELECT is NULL.

    - -

    Both simple and aggregate functions are supported. A simple -function can be used in any expression. Simple functions return -a result immediately based on their inputs. Aggregate functions -may only be used in a SELECT statement. Aggregate functions compute -their result across all rows of the result set.

    - -

    The functions shown below are available by default. Additional -functions may be written in C and added to the database engine using -the sqlite3_create_function() -API.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    abs(X)Return the absolute value of argument X.
    coalesce(X,Y,...)Return a copy of the first non-NULL argument. If -all arguments are NULL then NULL is returned. There must be at least -2 arguments.
    glob(X,Y)This function is used to implement the -"X GLOB Y" syntax of SQLite. The -sqlite3_create_function() -interface can -be used to override this function and thereby change the operation -of the GLOB operator.
    ifnull(X,Y)Return a copy of the first non-NULL argument. If -both arguments are NULL then NULL is returned. This behaves the same as -coalesce() above.
    last_insert_rowid()Return the ROWID of the last row insert from this -connection to the database. This is the same value that would be returned -from the sqlite_last_insert_rowid() API function.
    length(X)Return the string length of X in characters. -If SQLite is configured to support UTF-8, then the number of UTF-8 -characters is returned, not the number of bytes.
    like(X,Y [,Z]) -This function is used to implement the "X LIKE Y [ESCAPE Z]" -syntax of SQL. If the optional ESCAPE clause is present, then the -user-function is invoked with three arguments. Otherwise, it is -invoked with two arguments only. The - -sqlite_create_function() interface can be used to override this -function and thereby change the operation of the LIKE operator. When doing this, it may be important -to override both the two and three argument versions of the like() -function. Otherwise, different code may be called to implement the -LIKE operator depending on whether or not an ESCAPE clause was -specified.
    lower(X)Return a copy of string X will all characters -converted to lower case. The C library tolower() routine is used -for the conversion, which means that this function might not -work correctly on UTF-8 characters.
    max(X,Y,...)Return the argument with the maximum value. Arguments -may be strings in addition to numbers. The maximum value is determined -by the usual sort order. Note that max() is a simple function when -it has 2 or more arguments but converts to an aggregate function if given -only a single argument.
    min(X,Y,...)Return the argument with the minimum value. Arguments -may be strings in addition to numbers. The minimum value is determined -by the usual sort order. Note that min() is a simple function when -it has 2 or more arguments but converts to an aggregate function if given -only a single argument.
    nullif(X,Y)Return the first argument if the arguments are different, -otherwise return NULL.
    quote(X)This routine returns a string which is the value of -its argument suitable for inclusion into another SQL statement. -Strings are surrounded by single-quotes with escapes on interior quotes -as needed. BLOBs are encoded as hexadecimal literals. -The current implementation of VACUUM uses this function. The function -is also useful when writing triggers to implement undo/redo functionality. -
    random(*)Return a random integer between -2147483648 and -+2147483647.
    round(X)
    round(X,Y)
    Round off the number X to Y digits to the -right of the decimal point. If the Y argument is omitted, 0 is -assumed.
    soundex(X)Compute the soundex encoding of the string X. -The string "?000" is returned if the argument is NULL. -This function is omitted from SQLite by default. -It is only available the -DSQLITE_SOUNDEX=1 compiler option -is used when SQLite is built.
    sqlite_version(*)Return the version string for the SQLite library -that is running. Example: "2.8.0"
    substr(X,Y,Z)Return a substring of input string X that begins -with the Y-th character and which is Z characters long. -The left-most character of X is number 1. If Y is negative -the the first character of the substring is found by counting from the -right rather than the left. If SQLite is configured to support UTF-8, -then characters indices refer to actual UTF-8 characters, not bytes.
    typeof(X)Return the type of the expression X. The only -return values are "null", "integer", "real", "text", and "blob". -SQLite's type handling is -explained in Datatypes in SQLite Version 3.
    upper(X)Return a copy of input string X converted to all -upper-case letters. The implementation of this function uses the C library -routine toupper() which means it may not work correctly on -UTF-8 strings.
    - -

    -The following aggregate functions are available by default. Additional -aggregate functions written in C may be added using the -sqlite3_create_function() -API.

    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    avg(X)Return the average value of all X within a group.
    count(X)
    count(*)
    The first form return a count of the number of times -that X is not NULL in a group. The second form (with no argument) -returns the total number of rows in the group.
    max(X)Return the maximum value of all values in the group. -The usual sort order is used to determine the maximum.
    min(X)Return the minimum non-NULL value of all values in the group. -The usual sort order is used to determine the minimum. NULL is only returned -if all values in the group are NULL.
    sum(X)Return the numeric sum of all values in the group.
    -} - - -Section INSERT insert - -Syntax {sql-statement} { -INSERT [OR ] INTO [ .] [()] VALUES() | -INSERT [OR ] INTO [ .] [()] -} - -puts { -

    The INSERT statement comes in two basic forms. The first form -(with the "VALUES" keyword) creates a single new row in an existing table. -If no column-list is specified then the number of values must -be the same as the number of columns in the table. If a column-list -is specified, then the number of values must match the number of -specified columns. Columns of the table that do not appear in the -column list are filled with the default value, or with NULL if not -default value is specified. -

    - -

    The second form of the INSERT statement takes it data from a -SELECT statement. The number of columns in the result of the -SELECT must exactly match the number of columns in the table if -no column list is specified, or it must match the number of columns -name in the column list. A new entry is made in the table -for every row of the SELECT result. The SELECT may be simple -or compound. If the SELECT statement has an ORDER BY clause, -the ORDER BY is ignored.

    - -

    The optional conflict-clause allows the specification of an alternative -constraint conflict resolution algorithm to use during this one command. -See the section titled -ON CONFLICT for additional information. -For compatibility with MySQL, the parser allows the use of the -single keyword REPLACE as an alias for "INSERT OR REPLACE". -

    -} - - -Section {ON CONFLICT clause} conflict - -Syntax {conflict-clause} { -ON CONFLICT -} {conflict-algorithm} { -ROLLBACK | ABORT | FAIL | IGNORE | REPLACE -} - -puts { -

    The ON CONFLICT clause is not a separate SQL command. It is a -non-standard clause that can appear in many other SQL commands. -It is given its own section in this document because it is not -part of standard SQL and therefore might not be familiar.

    - -

    The syntax for the ON CONFLICT clause is as shown above for -the CREATE TABLE and CREATE INDEX commands. For the COPY, INSERT, and -UPDATE commands, the keywords "ON CONFLICT" are replaced by "OR", to make -the syntax seem more natural. But the meaning of the clause is the same -either way.

    - -

    The ON CONFLICT clause specifies an algorithm used to resolve -constraint conflicts. There are five choices: ROLLBACK, ABORT, -FAIL, IGNORE, and REPLACE. The default algorithm is ABORT. This -is what they mean:

    - -
    -
    ROLLBACK
    -

    When a constraint violation occurs, an immediate ROLLBACK -occurs, thus ending the current transaction, and the command aborts -with a return code of SQLITE_CONSTRAINT. If no transaction is -active (other than the implied transaction that is created on every -command) then this algorithm works the same as ABORT.

    - -
    ABORT
    -

    When a constraint violation occurs, the command backs out -any prior changes it might have made and aborts with a return code -of SQLITE_CONSTRAINT. But no ROLLBACK is executed so changes -from prior commands within the same transaction -are preserved. This is the default behavior.

    - -
    FAIL
    -

    When a constraint violation occurs, the command aborts with a -return code SQLITE_CONSTRAINT. But any changes to the database that -the command made prior to encountering the constraint violation -are preserved and are not backed out. For example, if an UPDATE -statement encountered a constraint violation on the 100th row that -it attempts to update, then the first 99 row changes are preserved -but changes to rows 100 and beyond never occur.

    - -
    IGNORE
    -

    When a constraint violation occurs, the one row that contains -the constraint violation is not inserted or changed. But the command -continues executing normally. Other rows before and after the row that -contained the constraint violation continue to be inserted or updated -normally. No error is returned.

    - -
    REPLACE
    -

    When a UNIQUE constraint violation occurs, the pre-existing rows -that are causing the constraint violation are removed prior to inserting -or updating the current row. Thus the insert or update always occurs. -The command continues executing normally. No error is returned. -If a NOT NULL constraint violation occurs, the NULL value is replaced -by the default value for that column. If the column has no default -value, then the ABORT algorithm is used.

    - -

    When this conflict resolution strategy deletes rows in order to -satisfy a constraint, it does not invoke delete triggers on those -rows. But that may change in a future release.

    -
    - -

    The algorithm specified in the OR clause of a COPY, INSERT, or UPDATE -overrides any algorithm specified in a CREATE TABLE or CREATE INDEX. -If no algorithm is specified anywhere, the ABORT algorithm is used.

    -} -#

    For additional information, see -# conflict.html.

    - -Section REINDEX reindex - -Syntax {sql-statement} { - REINDEX -} -Syntax {sql-statement} { - REINDEX [ .] -} - -puts { -

    The REINDEX command is used to delete and recreate indices from scratch. -This is primarily useful when the definition of a collation sequence has -changed. -

    - -

    In the first form, all indices in all attached databases that use the -named collation sequence are recreated. In the second form, if -[database-name.]table/index-name identifies a table, then all indices -associated with the table are rebuilt. If an index is identified, then only -this specific index is deleted and recreated. -

    - -

    If no database-name is specified and there exists both a table or -index and a collation sequence of the specified name, then indices associated -with the collation sequence only are reconstructed. This ambiguity may be -dispelled by always specifying a database-name when reindexing a -specific table or index. -} - -Section REPLACE replace - -Syntax {sql-statement} { -REPLACE INTO [ .] [( )] VALUES ( ) | -REPLACE INTO [ .] [( )] -} - -puts { -

    The REPLACE command is an alias for the "INSERT OR REPLACE" variant -of the INSERT command. This alias is provided for -compatibility with MySQL. See the -INSERT command documentation for additional -information.

    -} - - -Section SELECT select - -Syntax {sql-statement} { -SELECT [ALL | DISTINCT] [FROM ] -[WHERE ] -[GROUP BY ] -[HAVING ] -[
    [
    ]* -} {table} { - [AS ] | -(
    - - - - - - -
    'keyword'A keyword in single quotes is interpreted as a literal string - if it occurs in a context where a string literal is allowed, otherwise - it is understood as an identifier.
    "keyword"A keyword in double-quotes is interpreted as an identifier if - it matches a known identifier. Otherwise it is interpreted as a - string literal.
    [keyword]A keyword enclosed in square brackets is always understood as - an identifier. This is not standard SQL. This quoting mechanism - is used by MS Access and SQL Server and is included in SQLite for - compatibility.
    - -

    - -

    Quoted keywords are unaesthetic. -To help you avoid them, SQLite allows many keywords to be used unquoted -as the names of databases, tables, indices, triggers, views, and/or columns. -In the list of keywords that follows, those that can be used as identifiers -are shown in an italic font. Keywords that must be quoted in order to be -used as identifiers are shown in bold.

    - -

    -SQLite adds new keywords from time to time when it take on new features. -So to prevent you code from being broken by future enhancements, you should -normally quote any indentifier that is an English language word, even if -you do not have to. -

    - -

    -The following are the keywords currently recognized by SQLite: -

    - -
    - - -
    -} - -set n [llength $keyword_list] -set nCol 5 -set nRow [expr {($n+$nCol-1)/$nCol}] -set i 0 -foreach word $keyword_list { - if {[string index $word end]=="*"} { - set word [string range $word 0 end-1] - set font i - } else { - set font b - } - if {$i==$nRow} { - puts "" - set i 1 - } else { - incr i - } - puts "<$font>$word
    " -} - -puts { -
    - -

    Special names

    - -

    The following are not keywords in SQLite, but are used as names of -system objects. They can be used as an identifier for a different -type of object.

    - -
    - _ROWID_
    - MAIN
    - OID
    - ROWID
    - SQLITE_MASTER
    - SQLITE_SEQUENCE
    - SQLITE_TEMP_MASTER
    - TEMP
    -
    -} - -footer $rcsid -if {[string length $outputdir]} { - footer $rcsid -} diff --git a/sqlite/www/oldnews.tcl b/sqlite/www/oldnews.tcl deleted file mode 100644 index 406a11d..0000000 --- a/sqlite/www/oldnews.tcl +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/tclsh -source common.tcl -header {SQLite Older News} - -proc newsitem {date title text} { - puts "

    $date - $title

    " - regsub -all "\n( *\n)+" $text "

    \n\n

    " txt - puts "

    $txt

    " - puts "
    " -} - -newsitem {2005-Feb-01} {Version 3.1.1 (beta) Released} { - Version 3.1.1 (beta) is now available on the - website. Verison 3.1.1 is fully backwards compatible with the 3.0 series - and features many new features including Autovacuum and correlated - subqueries. The - release notes - From version 3.1.0 apply equally to this release beta. A stable release - is expected within a couple of weeks. -} - -newsitem {2005-Jan-21} {Version 3.1.0 (alpha) Released} { - Version 3.1.0 (alpha) is now available on the - website. Verison 3.1.0 is fully backwards compatible with the 3.0 series - and features many new features including Autovacuum and correlated - subqueries. See the - release notes - for details. - - This is an alpha release. A beta release is expected in about a week - with the first stable release to follow after two more weeks. -} - -newsitem {2004-Oct-11} {Version 3.0.8} { - Version 3.0.8 of SQLite contains several code optimizations and minor - bug fixes and adds support for DEFERRED, IMMEDIATE, and EXCLUSIVE - transactions. This is an incremental release. There is no reason - to upgrade from version 3.0.7 if that version is working for you. -} - -newsitem {2004-Sep-18} {Version 3.0.7} { - Version 3.0 has now been in use by multiple projects for several - months with no major difficulties. We consider it stable and - ready for production use. -} - -newsitem {2004-Sep-02} {Version 3.0.6 (beta)} { - Because of some important changes to sqlite3_step(), - we have decided to - do an additional beta release prior to the first "stable" release. - If no serious problems are discovered in this version, we will - release version 3.0 "stable" in about a week. -} - - -newsitem {2004-Aug-29} {Version 3.0.5 (beta)} { - The fourth beta release of SQLite version 3.0 is now available. - The next release is expected to be called "stable". -} - - -newsitem {2004-Aug-08} {Version 3.0.4 (beta)} { - The third beta release of SQLite version 3.0 is now available. - This new beta fixes several bugs including a database corruption - problem that can occur when doing a DELETE while a SELECT is pending. - Expect at least one more beta before version 3.0 goes final. -} - -newsitem {2004-July-22} {Version 3.0.3 (beta)} { - The second beta release of SQLite version 3.0 is now available. - This new beta fixes many bugs and adds support for databases with - varying page sizes. The next 3.0 release will probably be called - a final or stable release. - - Version 3.0 adds support for internationalization and a new - more compact file format. - Details. - The API and file format have been fixed since 3.0.2. All - regression tests pass (over 100000 tests) and the test suite - exercises over 95% of the code. - - SQLite version 3.0 is made possible in part by AOL - developers supporting and embracing great Open-Source Software. -} - -newsitem {2004-Jly-22} {Version 2.8.15} { - SQLite version 2.8.15 is a maintenance release for the version 2.8 - series. Version 2.8 continues to be maintained with bug fixes, but - no new features will be added to version 2.8. All the changes in - this release are minor. If you are not having problems, there is - there is no reason to upgrade. -} - -newsitem {2004-Jun-30} {Version 3.0.2 (beta) Released} { - The first beta release of SQLite version 3.0 is now available. - Version 3.0 adds support for internationalization and a new - more compact file format. - Details. - As of this release, the API and file format are frozen. All - regression tests pass (over 100000 tests) and the test suite - exercises over 95% of the code. - - SQLite version 3.0 is made possible in part by AOL - developers supporting and embracing great Open-Source Software. -} - - -newsitem {2004-Jun-25} {Website hacked} { - The www.sqlite.org website was hacked sometime around 2004-Jun-22 - because the lead SQLite developer failed to properly patch CVS. - Evidence suggests that the attacker was unable to elevate privileges - above user "cvs". Nevertheless, as a precaution the entire website - has been reconstructed from scratch on a fresh machine. All services - should be back to normal as of 2004-Jun-28. -} - - -newsitem {2004-Jun-18} {Version 3.0.0 (alpha) Released} { - The first alpha release of SQLite version 3.0 is available for - public review and comment. Version 3.0 enhances internationalization support - through the use of UTF-16 and user-defined text collating sequences. - BLOBs can now be stored directly, without encoding. - A new file format results in databases that are 25% smaller (depending - on content). The code is also a little faster. In spite of the many - new features, the library footprint is still less than 240KB - (x86, gcc -O1). - Additional information. - - Our intent is to freeze the file format and API on 2004-Jul-01. - Users are encouraged to review and evaluate this alpha release carefully - and submit any feedback prior to that date. - - The 2.8 series of SQLite will continue to be supported with bug - fixes for the foreseeable future. -} - -newsitem {2004-Jun-09} {Version 2.8.14 Released} { - SQLite version 2.8.14 is a patch release to the stable 2.8 series. - There is no reason to upgrade if 2.8.13 is working ok for you. - This is only a bug-fix release. Most development effort is - going into version 3.0.0 which is due out soon. -} - -newsitem {2004-May-31} {CVS Access Temporarily Disabled} { - Anonymous access to the CVS repository will be suspended - for 2 weeks beginning on 2004-June-04. Everyone will still - be able to download - prepackaged source bundles, create or modify trouble tickets, or view - change logs during the CVS service interruption. Full open access to the - CVS repository will be restored on 2004-June-18. -} - -newsitem {2004-Apr-23} {Work Begins On SQLite Version 3} { - Work has begun on version 3 of SQLite. Version 3 is a major - changes to both the C-language API and the underlying file format - that will enable SQLite to better support internationalization. - The first beta is schedule for release on 2004-July-01. - - Plans are to continue to support SQLite version 2.8 with - bug fixes. But all new development will occur in version 3.0. -} -footer {$Id: oldnews.tcl,v 1.10 2005/02/15 12:51:16 drh Exp $} diff --git a/sqlite/www/omitted.tcl b/sqlite/www/omitted.tcl deleted file mode 100644 index 602cbe6..0000000 --- a/sqlite/www/omitted.tcl +++ /dev/null @@ -1,94 +0,0 @@ -# -# Run this script to generated a omitted.html output file -# -set rcsid {$Id: omitted.tcl,v 1.7 2005/01/21 18:19:29 drh Exp $} -source common.tcl -header {SQL Features That SQLite Does Not Implement} -puts { -

    SQL Features That SQLite Does Not Implement

    - -

    -Rather than try to list all the features of SQL92 that SQLite does -support, it is much easier to list those that it does not. -Unsupported features of SQL92 are shown below.

    - -

    -The order of this list gives some hint as to when a feature might -be added to SQLite. Those features near the top of the list are -likely to be added in the near future. There are no immediate -plans to add features near the bottom of the list. -

    - - -} - -proc feature {name desc} { - puts "" - puts "" -} - -feature {CHECK constraints} { - CHECK constraints are parsed but they are not enforced. - NOT NULL and UNIQUE constraints are enforced, however. -} - -feature {FOREIGN KEY constraints} { - FOREIGN KEY constraints are parsed but are not enforced. -} - -feature {Complete trigger support} { - There is some support for triggers but it is not complete. Missing - subfeatures include FOR EACH STATEMENT triggers (currently all triggers - must be FOR EACH ROW), INSTEAD OF triggers on tables (currently - INSTEAD OF triggers are only allowed on views), and recursive - triggers - triggers that trigger themselves. -} - -feature {ALTER TABLE} { - To change a table you have to delete it (saving its contents to a temporary - table) and recreate it from scratch. - ("ALTER TABLE ... RENAME TABLE ..." was added to version 3.1.0.) -} - -feature {Nested transactions} { - The current implementation only allows a single active transaction. -} - -feature {The COUNT(DISTINCT X) function} { - You can accomplish the same thing using a subquery, like this:
    -   SELECT count(x) FROM (SELECT DISTINCT x FROM tbl); -} - -feature {RIGHT and FULL OUTER JOIN} { - LEFT OUTER JOIN is implemented, but not RIGHT OUTER JOIN or - FULL OUTER JOIN. -} - -feature {Writing to VIEWs} { - VIEWs in SQLite are read-only. You may not execute a DELETE, INSERT, or - UPDATE statement on a view. But you can create a trigger - that fires on an attempt to DELETE, INSERT, or UPDATE a view and do - what you need in the body of the trigger. -} - -feature {GRANT and REVOKE} { - Since SQLite reads and writes an ordinary disk file, the - only access permissions that can be applied are the normal - file access permissions of the underlying operating system. - The GRANT and REVOKE commands commonly found on client/server - RDBMSes are not implemented because they would be meaningless - for an embedded database engine. -} - -puts { -
    $name " - puts "$desc
    - -

    -If you find other SQL92 features that SQLite does not support, please -add them to the Wiki page at - -http://www.sqlite.org/cvstrac/wiki?p=Unsupported -

    -} -footer $rcsid diff --git a/sqlite/www/optimizing.tcl b/sqlite/www/optimizing.tcl deleted file mode 100644 index 44d2825..0000000 --- a/sqlite/www/optimizing.tcl +++ /dev/null @@ -1,15 +0,0 @@ -set rcsid {$Id: optimizing.tcl,v 1.1 2005/01/17 03:42:52 drh Exp $} -source common.tcl -header {Hints For Optimizing Queries In SQLite} -proc section {level tag name} { - incr level - if {$level>6} {set level 6} - puts "\n"" - puts "$name\n" -} -section 1 recompile {Recompile the library for optimal performance} -section 2 avoidtrans {Minimize the number of transactions} -section 3 usebind {Use sqlite3_bind to insert large chunks of data} -section 4 useindices {Use appropriate indices} -section 5 recordjoin {Reorder the tables in a join} -footer $rcsid diff --git a/sqlite/www/pragma.tcl b/sqlite/www/pragma.tcl deleted file mode 100644 index aaefbc4..0000000 --- a/sqlite/www/pragma.tcl +++ /dev/null @@ -1,443 +0,0 @@ -# -# Run this Tcl script to generate the pragma.html file. -# -set rcsid {$Id: pragma.tcl,v 1.8 2005/01/10 06:39:57 danielk1977 Exp $} -source common.tcl -header {Pragma statements supported by SQLite} - -proc Section {name {label {}}} { - puts "\n
    " - if {$label!=""} { - puts "
    " - } - puts "

    $name

    \n" -} - -puts { -

    The PRAGMA command is a special command used to -modify the operation of the SQLite library or to query the library for -internal (non-table) data. The PRAGMA command is issued using the same -interface as other SQLite commands (e.g. SELECT, INSERT) but is different -different in the following important respects: -

    -
      -
    • Specific pragma statements may be removed and others added in future - releases of SQLite. Use with caution! -
    • No error messages are generated if an unknown pragma is issued. - Unknown pragmas are simply ignored. This means if there is a typo in - a pragma statement the library does not inform the user of the fact. -
    • Some pragmas take effect during the SQL compilation stage, not the - execution stage. This means if using the C-language sqlite3_compile(), - sqlite3_step(), sqlite3_finalize() API (or similar in a wrapper - interface), the pragma may be applied to the library during the - sqlite3_compile() call. -
    • The pragma command is unlikely to be compatible with any other SQL - engine. -
    - -

    The available pragmas fall into four basic categories:

    - -} - -Section {PRAGMA command syntax} syntax - -Syntax {sql-statement} { -PRAGMA [= ] | -PRAGMA () -} - -puts { -

    The pragmas that take an integer value also accept -symbolic names. The strings "on", "true", and "yes" -are equivalent to 1. The strings "off", "false", -and "no" are equivalent to 0. These strings are case- -insensitive, and do not require quotes. An unrecognized string will be -treated as 1, and will not generate an error. When the value -is returned it is as an integer.

    -} - -Section {Pragmas to modify library operation} modify - -puts { -
      - -
    • PRAGMA auto_vacuum; -
      PRAGMA auto_vacuum =
      0 | 1;

      -

      Query or set the auto-vacuum flag in the database.

      - -

      Normally, when a transaction that deletes data from a database is - committed, the database file remains the same size. Unused database file - pages are marked as such and reused later on, when data is inserted into - the database. In this mode the VACUUM - command is used to reclaim unused space.

      - -

      When the auto-vacuum flag is set, the database file shrinks when a - transaction that deletes data is committed (The VACUUM command is not - useful in a database with the auto-vacuum flag set). To support this - functionality the database stores extra information internally, resulting - in slightly larger database files than would otherwise be possible.

      - -

      It is only possible to modify the value of the auto-vacuum flag before - any tables have been created in the database. No error message is - returned if an attempt to modify the auto-vacuum flag is made after - one or more tables have been created. -

    • - - -
    • PRAGMA cache_size; -
      PRAGMA cache_size =
      Number-of-pages;

      -

      Query or change the maximum number of database disk pages that SQLite - will hold in memory at once. Each page uses about 1.5K of memory. - The default cache size is 2000. If you are doing UPDATEs or DELETEs - that change many rows of a database and you do not mind if SQLite - uses more memory, you can increase the cache size for a possible speed - improvement.

      -

      When you change the cache size using the cache_size pragma, the - change only endures for the current session. The cache size reverts - to the default value when the database is closed and reopened. Use - the default_cache_size - pragma to check the cache size permanently.

    • - - -
    • PRAGMA count_changes; -
      PRAGMA count_changes =
      0 | 1;

      -

      Query or change the count-changes flag. Normally, when the - count-changes flag is not set, INSERT, UPDATE and DELETE statements - return no data. When count-changes is set, each of these commands - returns a single row of data consisting of one integer value - the - number of rows inserted, modified or deleted by the command. The - returned change count does not include any insertions, modifications - or deletions performed by triggers.

      - - -
    • PRAGMA default_cache_size; -
      PRAGMA default_cache_size =
      Number-of-pages;

      -

      Query or change the maximum number of database disk pages that SQLite - will hold in memory at once. Each page uses 1K on disk and about - 1.5K in memory. - This pragma works like the - cache_size - pragma with the additional - feature that it changes the cache size persistently. With this pragma, - you can set the cache size once and that setting is retained and reused - every time you reopen the database.

    • - - -
    • PRAGMA empty_result_callbacks; -
      PRAGMA empty_result_callbacks =
      0 | 1;

      -

      Query or change the empty-result-callbacks flag.

      -

      The empty-result-callbacks flag affects the sqlite3_exec API only. - Normally, when the empty-result-callbacks flag is cleared, the - callback function supplied to the sqlite3_exec() call is not invoked - for commands that return zero rows of data. When empty-result-callbacks - is set in this situation, the callback function is invoked exactly once, - with the third parameter set to 0 (NULL). This is to enable programs - that use the sqlite3_exec() API to retrieve column-names even when - a query returns no data. -

      - - -
    • PRAGMA encoding; -
      PRAGMA encoding = "UTF-8"; -
      PRAGMA encoding = "UTF-16"; -
      PRAGMA encoding = "UTF-16le"; -
      PRAGMA encoding = "UTF-16be";

      -

      In it's first form, if the main database has already been - created, then this pragma returns the text encoding used by the - main database, one of "UTF-8", "UTF-16le" (little-endian UTF-16 - encoding) or "UTF-16be" (big-endian UTF-16 encoding). If the main - database has not already been created, then the value returned is the - text encoding that will be used to create the main database, if - it is created by this session.

      -

      The second and subsequent forms of this pragma are only useful if - the main database has not already been created. In this case the - pragma sets the encoding that the main database will be created with if - it is created by this session. The string "UTF-16" is interpreted - as "UTF-16 encoding using native machine byte-ordering".

      -

      Databases created by the ATTACH command always use the same encoding - as the main database.

      -
    • - - -
    • PRAGMA full_column_names; -
      PRAGMA full_column_names =
      0 | 1;

      -

      Query or change the full-column-names flag. This flag affects - the way SQLite names columns of data returned by SELECT statements - when the expression for the column is a table-column name or the - wildcard "*". Normally, such result columns are named - . if the SELECT statement joins two or - more tables together, or simply if the SELECT - statement queries a single table. When the full-column-names flag - is set, such columns are always named ., - regardless of whether or not a join is performed. -

      -

      If both the short-column-names and full-column-names are set, - then the behaviour associated with the full-column-names flag is - exhibited. -

      -
    • - - -
    • PRAGMA page_size; -
      PRAGMA page_size =
      bytes;

      -

      Query or set the page-size of the database. The page-size - may only be set if the database has not yet been created. The page - size must be a power of two greater than or equal to 512 and less - than or equal to 8192. The upper limit may be modified by setting - the value of macro SQLITE_MAX_PAGE_SIZE during compilation. -

      -
    • - - -
    • PRAGMA full_column_names; -
      PRAGMA full_column_names =
      0 | 1;

      -

      Query or change the short-column-names flag. This flag affects - the way SQLite names columns of data returned by SELECT statements - when the expression for the column is a table-column name or the - wildcard "*". Normally, such result columns are named - . if the SELECT statement joins two or - more tables together, or simply if the SELECT - statement queries a single table. When the short-column-names flag - is set, such columns are always named , regardless of - whether or not a join is performed. -

      -

      If both the short-column-names and full-column-names are set, - then the behaviour associated with the full-column-names flag is - exhibited. -

      -
    • - - -
    • PRAGMA synchronous; -
      PRAGMA synchronous = FULL;
      (2) -
      PRAGMA synchronous = NORMAL;
      (1) -
      PRAGMA synchronous = OFF;
      (0)

      -

      Query or change the setting of the "synchronous" flag. - The first (query) form will return the setting as an - integer. When synchronous is FULL (2), the SQLite database engine will - pause at critical moments to make sure that data has actually been - written to the disk surface before continuing. This ensures that if - the operating system crashes or if there is a power failure, the database - will be uncorrupted after rebooting. FULL synchronous is very - safe, but it is also slow. - When synchronous is NORMAL (1, the default), the SQLite database - engine will still pause at the most critical moments, but less often - than in FULL mode. There is a very small (though non-zero) chance that - a power failure at just the wrong time could corrupt the database in - NORMAL mode. But in practice, you are more likely to suffer - a catastrophic disk failure or some other unrecoverable hardware - fault. So NORMAL is the default mode. - With synchronous OFF (0), SQLite continues without pausing - as soon as it has handed data off to the operating system. - If the application running SQLite crashes, the data will be safe, but - the database might become corrupted if the operating system - crashes or the computer loses power before that data has been written - to the disk surface. On the other hand, some - operations are as much as 50 or more times faster with synchronous OFF. -

    • - - - -
    • PRAGMA temp_store; -
      PRAGMA temp_store = DEFAULT;
      (0) -
      PRAGMA temp_store = MEMORY;
      (2) -
      PRAGMA temp_store = FILE;
      (1)

      -

      Query or change the setting of the "temp_store" flag affecting - the database for the duration of the current database connection. - The temp_store flag reverts to its default value when the database - is closed and reopened. For additional information on the temp_store - flag, see the description of the - default_temp_store pragma. Note that it is possible for - the library compile-time options to override this setting. - - -

    • PRAGMA temp_store; -
      PRAGMA temp_store = DEFAULT;
      (0) -
      PRAGMA temp_store = MEMORY;
      (2) -
      PRAGMA temp_store = FILE;
      (1)

      -

      Query or change the setting of the "temp_store" parameter. - When temp_store is DEFAULT (0), the compile-time value of the - symbol TEMP_STORE is used for the temporary database. When - temp_store is MEMORY (2), an in-memory database is used. - When temp_store is FILE (1), a temporary database file on disk - will be used. See PRAGMA - temp_store_directory for further temporary storage options when - FILE is specified. When the temp_store setting is changed, - all existing temporary tables, indices, triggers, and viewers are - immediately deleted.

      - -

      It is possible for the library compile-time symbol - TEMP_STORE to override this setting. The following table summarizes - this:

      - - - - - - - - - - - -
      TEMP_STOREtemp_storetemp database location
      0anyfile
      10file
      11file
      12memory
      20memory
      21file
      22memory
      3anymemory
      -
    • -
      - - -
    • PRAGMA temp_store_directory; -
      PRAGMA temp_store_directory = 'directory-name';

      -

      Query or change the setting of the "temp_store_directory" flag affecting - the database for the duration of the current database connection. - The temp_store_directory flag reverts to its default value when the database - is closed and reopened. Setting temp_store_directory allows control of the - placement of temporary files created by SQLite when PRAGMA - temp_store is FILE (1), - or when the compile time default temporary store is FILE. - Otherwise, when the temp_store (or default) setting is - MEMORY (2), setting temp_store_directory has no effect.

      - -

      When the temp_store_directory setting is changed, all existing temporary - tables, indices, triggers, and viewers are immediately deleted. In - practice, temp_store_directory should be set immediately after the - database is opened.

      - -

      The value directory-name should be enclosed in single quotes. - To revert the directory to the default, set the directory-name to - a null string, e.g., PRAGMA temp_store_directory = ''. An - error is raised if directory-name is not found or is not - writable.

      - -

      The default directory for temporary files depends on the OS. For - Unix/Linux/OSX, the default is the is the first writable directory found - in the list of: /var/tmp, /usr/tmp, /tmp, and - current-directory. For Windows NT, the default - directory is determined by Windows, generally - C:\Documents and Settings\user-name\Local Settings\Temp\. - Temporary files created by SQLite are unlinked immediately after - opening, so that the operating system can automatically delete the - files when the SQLite process exits. Thus, temporary files are not - normally visible through ls or dir commands.

      - -
    • -
    -} - -Section {Pragmas to query the database schema} schema - -puts { -
      - -
    • PRAGMA database_list;

      -

      For each open database, invoke the callback function once with - information about that database. Arguments include the index and - the name the database was attached with. The first row will be for - the main database. The second row will be for the database used to - store temporary tables.

    • - - -
    • PRAGMA foreign_key_list(table-name);

      -

      For each foreign key that references a column in the argument - table, invoke the callback function with information about that - foreign key. The callback function will be invoked once for each - column in each foreign key.

    • - - -
    • PRAGMA index_info(index-name);

      -

      For each column that the named index references, invoke the - callback function - once with information about that column, including the column name, - and the column number.

    • - - -
    • PRAGMA index_list(table-name);

      -

      For each index on the named table, invoke the callback function - once with information about that index. Arguments include the - index name and a flag to indicate whether or not the index must be - unique.

    • - - -
    • PRAGMA table_info(table-name);

      -

      For each column in the named table, invoke the callback function - once with information about that column, including the column name, - data type, whether or not the column can be NULL, and the default - value for the column.

    • -
    -} - -Section {Pragmas to query/modify version values} version - -puts { - -
      - - -
    • PRAGMA [database.]schema_version; -
      PRAGMA [database.]schema_version =
      integer ; -
      PRAGMA [database.]user_version; -
      PRAGMA [database.]user_version =
      integer ; - - -

      The pragmas 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-version 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.

      -
    • -
    -} - -Section {Pragmas to debug the library} debug - -puts { -
      - -
    • PRAGMA integrity_check;

      -

      The command does an integrity check of the entire database. It - looks for out-of-order records, missing pages, malformed records, and - corrupt indices. - If any problems are found, then a single string is returned which is - a description of all problems. If everything is in order, "ok" is - returned.

    • - - -
    • PRAGMA parser_trace = ON; (1) -
      PRAGMA parser_trace = OFF;
      (0)

      -

      Turn tracing of the SQL parser inside of the - SQLite library on and off. This is used for debugging. - This only works if the library is compiled without the NDEBUG macro. -

    • - - -
    • PRAGMA vdbe_trace = ON; (1) -
      PRAGMA vdbe_trace = OFF;
      (0)

      -

      Turn tracing of the virtual database engine inside of the - SQLite library on and off. This is used for debugging. See the - VDBE documentation for more - information.

    • -
    - -} - diff --git a/sqlite/www/quickstart.tcl b/sqlite/www/quickstart.tcl deleted file mode 100644 index c096c6a..0000000 --- a/sqlite/www/quickstart.tcl +++ /dev/null @@ -1,108 +0,0 @@ -# -# Run this TCL script to generate HTML for the quickstart.html file. -# -set rcsid {$Id: quickstart.tcl,v 1.6 2004/10/19 01:31:20 drh Exp $} -source common.tcl -header {SQLite In 5 Minutes Or Less} -puts { -

    Here is what you do to start experimenting with SQLite without having -to do a lot of tedious reading and configuration:

    - -

    Download The Code

    - -
      -
    • Get a copy of the prebuilt binaries for your machine, or get a copy -of the sources and compile them yourself. Visit -the download page for more information.

    • -
    - -

    Create A New Database

    - -
      -
    • At a shell or DOS prompt, enter: "sqlite3 test.db". This will -create a new database named "test.db". (You can use a different name if -you like.)

    • -
    • Enter SQL commands at the prompt to create and populate the -new database.

    • -
    - -

    Write Programs That Use SQLite

    - -
      -
    • Below is a simple TCL program that demonstrates how to use -the TCL interface to SQLite. The program executes the SQL statements -given as the second argument on the database defined by the first -argument. The commands to watch for are the sqlite3 command -on line 7 which opens an SQLite database and creates -a new TCL command named "db" to access that database, the -invocation of the db command on line 8 to execute -SQL commands against the database, and the closing of the database connection -on the last line of the script.

      - -
      -#!/usr/bin/tclsh
      -if {$argc!=2} {
      -  puts stderr "Usage: %s DATABASE SQL-STATEMENT"
      -  exit 1
      -}
      -load /usr/lib/tclsqlite3.so Sqlite3
      -sqlite3 db [lindex $argv 0]
      -db eval [lindex $argv 1] x {
      -  foreach v $x(*) {
      -    puts "$v = $x($v)"
      -  }
      -  puts ""
      -}
      -db close
      -
      -
    • - -
    • Below is a simple C program that demonstrates how to use -the C/C++ interface to SQLite. The name of a database is given by -the first argument and the second argument is one or more SQL statements -to execute against the database. The function calls to pay attention -to here are the call to sqlite3_open() on line 22 which opens -the database, sqlite3_exec() on line 27 that executes SQL -commands against the database, and sqlite3_close() on line 31 -that closes the database connection.

      - -
      -#include <stdio.h>
      -#include <sqlite3.h>
      -
      -static int callback(void *NotUsed, int argc, char **argv, char **azColName){
      -  int i;
      -  for(i=0; i<argc; i++){
      -    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
      -  }
      -  printf("\n");
      -  return 0;
      -}
      -
      -int main(int argc, char **argv){
      -  sqlite3 *db;
      -  char *zErrMsg = 0;
      -  int rc;
      -
      -  if( argc!=3 ){
      -    fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
      -    exit(1);
      -  }
      -  rc = sqlite3_open(argv[1], &db);
      -  if( rc ){
      -    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      -    sqlite3_close(db);
      -    exit(1);
      -  }
      -  rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
      -  if( rc!=SQLITE_OK ){
      -    fprintf(stderr, "SQL error: %s\n", zErrMsg);
      -  }
      -  sqlite3_close(db);
      -  return 0;
      -}
      -
      -
    • -
    -} -footer {$Id: quickstart.tcl,v 1.6 2004/10/19 01:31:20 drh Exp $} diff --git a/sqlite/www/speed.tcl b/sqlite/www/speed.tcl deleted file mode 100644 index e6d7f9e..0000000 --- a/sqlite/www/speed.tcl +++ /dev/null @@ -1,495 +0,0 @@ -# -# Run this Tcl script to generate the speed.html file. -# -set rcsid {$Id: speed.tcl,v 1.16 2005/01/21 18:19:29 drh Exp $ } -source common.tcl -header {SQLite Database Speed Comparison} - -puts { -

    Database Speed Comparison

    - - -Note: This document is old. It describes a speed comparison between -an older version of SQLite against archic versions of MySQL and PostgreSQL. -Readers are invited to contribute more up-to-date speed comparisons -on the SQLite Wiki. -

    -The numbers here are old enough to be nearly meaningless. Until it is -updated, use this document only as proof that SQLite is not a -sluggard. - - -

    Executive Summary

    - -

    A series of tests were run to measure the relative performance of -SQLite 2.7.6, PostgreSQL 7.1.3, and MySQL 3.23.41. -The following are general -conclusions drawn from these experiments: -

    - -
      -
    • - SQLite 2.7.6 is significantly faster (sometimes as much as 10 or - 20 times faster) than the default PostgreSQL 7.1.3 installation - on RedHat 7.2 for most common operations. -

    • -
    • - SQLite 2.7.6 is often faster (sometimes - more than twice as fast) than MySQL 3.23.41 - for most common operations. -

    • -
    • - SQLite does not execute CREATE INDEX or DROP TABLE as fast as - the other databases. But this is not seen as a problem because - those are infrequent operations. -

    • -
    • - SQLite works best if you group multiple operations together into - a single transaction. -

    • -
    - -

    -The results presented here come with the following caveats: -

    - -
      -
    • - These tests did not attempt to measure multi-user performance or - optimization of complex queries involving multiple joins and subqueries. -

    • -
    • - These tests are on a relatively small (approximately 14 megabyte) database. - They do not measure how well the database engines scale to larger problems. -

    • -
    - -

    Test Environment

    - -

    -The platform used for these tests is a 1.6GHz Athlon with 1GB or memory -and an IDE disk drive. The operating system is RedHat Linux 7.2 with -a stock kernel. -

    - -

    -The PostgreSQL and MySQL servers used were as delivered by default on -RedHat 7.2. (PostgreSQL version 7.1.3 and MySQL version 3.23.41.) -No effort was made to tune these engines. Note in particular -the the default MySQL configuration on RedHat 7.2 does not support -transactions. Not having to support transactions gives MySQL a -big speed advantage, but SQLite is still able to hold its own on most -tests. -

    - -

    -I am told that the default PostgreSQL configuration in RedHat 7.3 -is unnecessarily conservative (it is designed to -work on a machine with 8MB of RAM) and that PostgreSQL could -be made to run a lot faster with some knowledgeable configuration -tuning. -Matt Sergeant reports that he has tuned his PostgreSQL installation -and rerun the tests shown below. His results show that -PostgreSQL and MySQL run at about the same speed. For Matt's -results, visit -

    - -
    - -http://www.sergeant.org/sqlite_vs_pgsync.html -
    - -

    -SQLite was tested in the same configuration that it appears -on the website. It was compiled with -O6 optimization and with -the -DNDEBUG=1 switch which disables the many "assert()" statements -in the SQLite code. The -DNDEBUG=1 compiler option roughly doubles -the speed of SQLite. -

    - -

    -All tests are conducted on an otherwise quiescent machine. -A simple Tcl script was used to generate and run all the tests. -A copy of this Tcl script can be found in the SQLite source tree -in the file tools/speedtest.tcl. -

    - -

    -The times reported on all tests represent wall-clock time -in seconds. Two separate time values are reported for SQLite. -The first value is for SQLite in its default configuration with -full disk synchronization turned on. With synchronization turned -on, SQLite executes -an fsync() system call (or the equivalent) at key points -to make certain that critical data has -actually been written to the disk drive surface. Synchronization -is necessary to guarantee the integrity of the database if the -operating system crashes or the computer powers down unexpectedly -in the middle of a database update. The second time reported for SQLite is -when synchronization is turned off. With synchronization off, -SQLite is sometimes much faster, but there is a risk that an -operating system crash or an unexpected power failure could -damage the database. Generally speaking, the synchronous SQLite -times are for comparison against PostgreSQL (which is also -synchronous) and the asynchronous SQLite times are for -comparison against the asynchronous MySQL engine. -

    - -

    Test 1: 1000 INSERTs

    -
    -CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));
    -INSERT INTO t1 VALUES(1,13153,'thirteen thousand one hundred fifty three');
    -INSERT INTO t1 VALUES(2,75560,'seventy five thousand five hundred sixty');
    -... 995 lines omitted
    -INSERT INTO t1 VALUES(998,66289,'sixty six thousand two hundred eighty nine');
    -INSERT INTO t1 VALUES(999,24322,'twenty four thousand three hundred twenty two');
    -INSERT INTO t1 VALUES(1000,94142,'ninety four thousand one hundred forty two');
    - -
    - - - - -
    PostgreSQL:   4.373
    MySQL:   0.114
    SQLite 2.7.6:   13.061
    SQLite 2.7.6 (nosync):   0.223
    - -

    -Because it does not have a central server to coordinate access, -SQLite must close and reopen the database file, and thus invalidate -its cache, for each transaction. In this test, each SQL statement -is a separate transaction so the database file must be opened and closed -and the cache must be flushed 1000 times. In spite of this, the asynchronous -version of SQLite is still nearly as fast as MySQL. Notice how much slower -the synchronous version is, however. SQLite calls fsync() after -each synchronous transaction to make sure that all data is safely on -the disk surface before continuing. For most of the 13 seconds in the -synchronous test, SQLite was sitting idle waiting on disk I/O to complete.

    - - -

    Test 2: 25000 INSERTs in a transaction

    -
    -BEGIN;
    -CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));
    -INSERT INTO t2 VALUES(1,59672,'fifty nine thousand six hundred seventy two');
    -... 24997 lines omitted
    -INSERT INTO t2 VALUES(24999,89569,'eighty nine thousand five hundred sixty nine');
    -INSERT INTO t2 VALUES(25000,94666,'ninety four thousand six hundred sixty six');
    -COMMIT;
    - -
    - - - - -
    PostgreSQL:   4.900
    MySQL:   2.184
    SQLite 2.7.6:   0.914
    SQLite 2.7.6 (nosync):   0.757
    - -

    -When all the INSERTs are put in a transaction, SQLite no longer has to -close and reopen the database or invalidate its cache between each statement. -It also does not -have to do any fsync()s until the very end. When unshackled in -this way, SQLite is much faster than either PostgreSQL and MySQL. -

    - -

    Test 3: 25000 INSERTs into an indexed table

    -
    -BEGIN;
    -CREATE TABLE t3(a INTEGER, b INTEGER, c VARCHAR(100));
    -CREATE INDEX i3 ON t3(c);
    -... 24998 lines omitted
    -INSERT INTO t3 VALUES(24999,88509,'eighty eight thousand five hundred nine');
    -INSERT INTO t3 VALUES(25000,84791,'eighty four thousand seven hundred ninety one');
    -COMMIT;
    - -
    - - - - -
    PostgreSQL:   8.175
    MySQL:   3.197
    SQLite 2.7.6:   1.555
    SQLite 2.7.6 (nosync):   1.402
    - -

    -There were reports that SQLite did not perform as well on an indexed table. -This test was recently added to disprove those rumors. It is true that -SQLite is not as fast at creating new index entries as the other engines -(see Test 6 below) but its overall speed is still better. -

    - -

    Test 4: 100 SELECTs without an index

    -
    -BEGIN;
    -SELECT count(*), avg(b) FROM t2 WHERE b>=0 AND b<1000;
    -SELECT count(*), avg(b) FROM t2 WHERE b>=100 AND b<1100;
    -... 96 lines omitted
    -SELECT count(*), avg(b) FROM t2 WHERE b>=9800 AND b<10800;
    -SELECT count(*), avg(b) FROM t2 WHERE b>=9900 AND b<10900;
    -COMMIT;
    - -
    - - - - -
    PostgreSQL:   3.629
    MySQL:   2.760
    SQLite 2.7.6:   2.494
    SQLite 2.7.6 (nosync):   2.526
    - - -

    -This test does 100 queries on a 25000 entry table without an index, -thus requiring a full table scan. Prior versions of SQLite used to -be slower than PostgreSQL and MySQL on this test, but recent performance -enhancements have increased its speed so that it is now the fastest -of the group. -

    - -

    Test 5: 100 SELECTs on a string comparison

    -
    -BEGIN;
    -SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%one%';
    -SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%two%';
    -... 96 lines omitted
    -SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%ninety nine%';
    -SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%one hundred%';
    -COMMIT;
    - -
    - - - - -
    PostgreSQL:   13.409
    MySQL:   4.640
    SQLite 2.7.6:   3.362
    SQLite 2.7.6 (nosync):   3.372
    - -

    -This test still does 100 full table scans but it uses -uses string comparisons instead of numerical comparisons. -SQLite is over three times faster than PostgreSQL here and about 30% -faster than MySQL. -

    - -

    Test 6: Creating an index

    -
    -CREATE INDEX i2a ON t2(a);
    CREATE INDEX i2b ON t2(b); -
    - - - - -
    PostgreSQL:   0.381
    MySQL:   0.318
    SQLite 2.7.6:   0.777
    SQLite 2.7.6 (nosync):   0.659
    - -

    -SQLite is slower at creating new indices. This is not a huge problem -(since new indices are not created very often) but it is something that -is being worked on. Hopefully, future versions of SQLite will do better -here. -

    - -

    Test 7: 5000 SELECTs with an index

    -
    -SELECT count(*), avg(b) FROM t2 WHERE b>=0 AND b<100;
    -SELECT count(*), avg(b) FROM t2 WHERE b>=100 AND b<200;
    -SELECT count(*), avg(b) FROM t2 WHERE b>=200 AND b<300;
    -... 4994 lines omitted
    -SELECT count(*), avg(b) FROM t2 WHERE b>=499700 AND b<499800;
    -SELECT count(*), avg(b) FROM t2 WHERE b>=499800 AND b<499900;
    -SELECT count(*), avg(b) FROM t2 WHERE b>=499900 AND b<500000;
    - -
    - - - - -
    PostgreSQL:   4.614
    MySQL:   1.270
    SQLite 2.7.6:   1.121
    SQLite 2.7.6 (nosync):   1.162
    - -

    -All three database engines run faster when they have indices to work with. -But SQLite is still the fastest. -

    - -

    Test 8: 1000 UPDATEs without an index

    -
    -BEGIN;
    -UPDATE t1 SET b=b*2 WHERE a>=0 AND a<10;
    -UPDATE t1 SET b=b*2 WHERE a>=10 AND a<20;
    -... 996 lines omitted
    -UPDATE t1 SET b=b*2 WHERE a>=9980 AND a<9990;
    -UPDATE t1 SET b=b*2 WHERE a>=9990 AND a<10000;
    -COMMIT;
    - -
    - - - - -
    PostgreSQL:   1.739
    MySQL:   8.410
    SQLite 2.7.6:   0.637
    SQLite 2.7.6 (nosync):   0.638
    - -

    -For this particular UPDATE test, MySQL is consistently -five or ten times -slower than PostgreSQL and SQLite. I do not know why. MySQL is -normally a very fast engine. Perhaps this problem has been addressed -in later versions of MySQL. -

    - -

    Test 9: 25000 UPDATEs with an index

    -
    -BEGIN;
    -UPDATE t2 SET b=468026 WHERE a=1;
    -UPDATE t2 SET b=121928 WHERE a=2;
    -... 24996 lines omitted
    -UPDATE t2 SET b=35065 WHERE a=24999;
    -UPDATE t2 SET b=347393 WHERE a=25000;
    -COMMIT;
    - -
    - - - - -
    PostgreSQL:   18.797
    MySQL:   8.134
    SQLite 2.7.6:   3.520
    SQLite 2.7.6 (nosync):   3.104
    - -

    -As recently as version 2.7.0, SQLite ran at about the same speed as -MySQL on this test. But recent optimizations to SQLite have more -than doubled speed of UPDATEs. -

    - -

    Test 10: 25000 text UPDATEs with an index

    -
    -BEGIN;
    -UPDATE t2 SET c='one hundred forty eight thousand three hundred eighty two' WHERE a=1;
    -UPDATE t2 SET c='three hundred sixty six thousand five hundred two' WHERE a=2;
    -... 24996 lines omitted
    -UPDATE t2 SET c='three hundred eighty three thousand ninety nine' WHERE a=24999;
    -UPDATE t2 SET c='two hundred fifty six thousand eight hundred thirty' WHERE a=25000;
    -COMMIT;
    - -
    - - - - -
    PostgreSQL:   48.133
    MySQL:   6.982
    SQLite 2.7.6:   2.408
    SQLite 2.7.6 (nosync):   1.725
    - -

    -Here again, version 2.7.0 of SQLite used to run at about the same speed -as MySQL. But now version 2.7.6 is over two times faster than MySQL and -over twenty times faster than PostgreSQL. -

    - -

    -In fairness to PostgreSQL, it started thrashing on this test. A -knowledgeable administrator might be able to get PostgreSQL to run a lot -faster here by tweaking and tuning the server a little. -

    - -

    Test 11: INSERTs from a SELECT

    -
    -BEGIN;
    INSERT INTO t1 SELECT b,a,c FROM t2;
    INSERT INTO t2 SELECT b,a,c FROM t1;
    COMMIT; -
    - - - - -
    PostgreSQL:   61.364
    MySQL:   1.537
    SQLite 2.7.6:   2.787
    SQLite 2.7.6 (nosync):   1.599
    - -

    -The asynchronous SQLite is just a shade slower than MySQL on this test. -(MySQL seems to be especially adept at INSERT...SELECT statements.) -The PostgreSQL engine is still thrashing - most of the 61 seconds it used -were spent waiting on disk I/O. -

    - -

    Test 12: DELETE without an index

    -
    -DELETE FROM t2 WHERE c LIKE '%fifty%'; -
    - - - - -
    PostgreSQL:   1.509
    MySQL:   0.975
    SQLite 2.7.6:   4.004
    SQLite 2.7.6 (nosync):   0.560
    - -

    -The synchronous version of SQLite is the slowest of the group in this test, -but the asynchronous version is the fastest. -The difference is the extra time needed to execute fsync(). -

    - -

    Test 13: DELETE with an index

    -
    -DELETE FROM t2 WHERE a>10 AND a<20000; -
    - - - - -
    PostgreSQL:   1.316
    MySQL:   2.262
    SQLite 2.7.6:   2.068
    SQLite 2.7.6 (nosync):   0.752
    - -

    -This test is significant because it is one of the few where -PostgreSQL is faster than MySQL. The asynchronous SQLite is, -however, faster then both the other two. -

    - -

    Test 14: A big INSERT after a big DELETE

    -
    -INSERT INTO t2 SELECT * FROM t1; -
    - - - - -
    PostgreSQL:   13.168
    MySQL:   1.815
    SQLite 2.7.6:   3.210
    SQLite 2.7.6 (nosync):   1.485
    - -

    -Some older versions of SQLite (prior to version 2.4.0) -would show decreasing performance after a -sequence of DELETEs followed by new INSERTs. As this test shows, the -problem has now been resolved. -

    - -

    Test 15: A big DELETE followed by many small INSERTs

    -
    -BEGIN;
    -DELETE FROM t1;
    -INSERT INTO t1 VALUES(1,10719,'ten thousand seven hundred nineteen');
    -... 11997 lines omitted
    -INSERT INTO t1 VALUES(11999,72836,'seventy two thousand eight hundred thirty six');
    -INSERT INTO t1 VALUES(12000,64231,'sixty four thousand two hundred thirty one');
    -COMMIT;
    - -
    - - - - -
    PostgreSQL:   4.556
    MySQL:   1.704
    SQLite 2.7.6:   0.618
    SQLite 2.7.6 (nosync):   0.406
    - -

    -SQLite is very good at doing INSERTs within a transaction, which probably -explains why it is so much faster than the other databases at this test. -

    - -

    Test 16: DROP TABLE

    -
    -DROP TABLE t1;
    DROP TABLE t2;
    DROP TABLE t3; -
    - - - - -
    PostgreSQL:   0.135
    MySQL:   0.015
    SQLite 2.7.6:   0.939
    SQLite 2.7.6 (nosync):   0.254
    - -

    -SQLite is slower than the other databases when it comes to dropping tables. -This probably is because when SQLite drops a table, it has to go through and -erase the records in the database file that deal with that table. MySQL and -PostgreSQL, on the other hand, use separate files to represent each table -so they can drop a table simply by deleting a file, which is much faster. -

    - -

    -On the other hand, dropping tables is not a very common operation -so if SQLite takes a little longer, that is not seen as a big problem. -

    - -} -footer $rcsid diff --git a/sqlite/www/support.tcl b/sqlite/www/support.tcl deleted file mode 100644 index 62536b5..0000000 --- a/sqlite/www/support.tcl +++ /dev/null @@ -1,79 +0,0 @@ -set rcsid {$Id: support.tcl,v 1.5 2004/11/01 16:03:12 drh Exp $} -source common.tcl -header {SQLite Support Options} -puts { -

    SQLite Support Options

    - - -

    Mailing List

    -

    -A mailing list has been set up for asking questions and -for open discussion of problems -and issues by the SQLite user community. -To subscribe to the mailing list, send an email to - -sqlite-users-subscribe@sqlite.org. -If you would prefer to get digests rather than individual -emails, send a message to to - -sqlite-users-digest-subscribe@sqlite.org. -For additional information about operating and using this -mailing list, send a message to - -sqlite-users-help@sqlite.org and instructions will be -sent by to you by return email. -

    - -

    -There are multiple archives of the mailing list: -

    - -
    - -http://www.mail-archive.com/sqlite-users%40sqlite.org
    - -http://www.theaimsgroup.com/
    - -http://news.gmane.org/gmane.comp.db.sqlite.general -
    - -

    - - -

    Direct E-Mail To The Author

    - -

    -Use the mailing list. -Please do not send email directly to the author of SQLite -unless: -

      -
    • You have or intend to acquire a professional support contract -as described below, or
    • -
    • You are working on an open source project.
    • -
    -You are welcomed to use SQLite in closed source, proprietary, and/or -commerical projects and to ask questions about such use on the public -mailing list. But please do not ask to receive free direct technical -support. The software is free; direct technical support is not. -

    - - -

    Professional Support

    - -

    -If you would like professional support for SQLite -or if you want custom modifications to SQLite performed by the -original author, these services are available for a modest fee. -For additional information visit - -http://www.hwaci.com/sw/sqlite/prosupport.html or contact:

    - -
    -D. Richard Hipp
    -Hwaci - Applied Software Research
    -704.948.4565
    -drh@hwaci.com -
    - -} -footer $rcsid diff --git a/sqlite/www/tclsqlite.tcl b/sqlite/www/tclsqlite.tcl deleted file mode 100644 index 69e00e8..0000000 --- a/sqlite/www/tclsqlite.tcl +++ /dev/null @@ -1,485 +0,0 @@ -# -# Run this Tcl script to generate the tclsqlite.html file. -# -set rcsid {$Id: tclsqlite.tcl,v 1.12 2004/12/17 15:41:13 tpoindex Exp $} -source common.tcl -header {The Tcl interface to the SQLite library} -proc METHOD {name text} { - puts "\n

    The \"$name\" method

    \n" - puts $text -} -puts { -

    The Tcl interface to the SQLite library

    - -

    The SQLite library is designed to be very easy to use from -a Tcl or Tcl/Tk script. This document gives an overview of the Tcl -programming interface.

    - -

    The API

    - -

    The interface to the SQLite library consists of single -tcl command named sqlite (version 2.8) or sqlite3 -(version 3.0). Because there is only this -one command, the interface is not placed in a separate -namespace.

    - -

    The sqlite3 command is used as follows:

    - -
    -sqlite3  dbcmd  database-name -
    - -

    -The sqlite3 command opens the database named in the second -argument. If the database does not already exist, it is -automatically created. -The sqlite3 command also creates a new Tcl -command to control the database. The name of the new Tcl command -is given by the first argument. This approach is similar to the -way widgets are created in Tk. -

    - -

    -The name of the database is just the name of a disk file in which -the database is stored. -

    - -

    -Once an SQLite database is open, it can be controlled using -methods of the dbcmd. There are currently 18 methods -defined:

    - -

    -

    -

    - -

    The use of each of these methods will be explained in the sequel, though -not in the order shown above.

    - -} - -############################################################################## -METHOD close { - -

    -As its name suggests, the "close" method to an SQLite database just -closes the database. This has the side-effect of deleting the -dbcmd Tcl command. Here is an example of opening and then -immediately closing a database: -

    - -
    -sqlite3 db1 ./testdb
    -db1 close
    -
    - -

    -If you delete the dbcmd directly, that has the same effect -as invoking the "close" method. So the following code is equivalent -to the previous:

    - -
    -sqlite3 db1 ./testdb
    -rename db1 {}
    -
    -} - -############################################################################## -METHOD eval { -

    -The most useful dbcmd method is "eval". The eval method is used -to execute SQL on the database. The syntax of the eval method looks -like this:

    - -
    -dbcmd  eval  sql -    ?array-name ? ?script? -
    - -

    -The job of the eval method is to execute the SQL statement or statements -given in the second argument. For example, to create a new table in -a database, you can do this:

    - -
    -sqlite3 db1 ./testdb
    -db1 eval {CREATE TABLE t1(a int, b text)}
    -
    - -

    The above code creates a new table named t1 with columns -a and b. What could be simpler?

    - -

    Query results are returned as a list of column values. If a -query requests 2 columns and there are 3 rows matching the query, -then the returned list will contain 6 elements. For example:

    - -
    -db1 eval {INSERT INTO t1 VALUES(1,'hello')}
    -db1 eval {INSERT INTO t1 VALUES(2,'goodbye')}
    -db1 eval {INSERT INTO t1 VALUES(3,'howdy!')}
    -set x [db1 eval {SELECT * FROM t1 ORDER BY a}]
    -
    - -

    The variable $x is set by the above code to

    - -
    -1 hello 2 goodbye 3 howdy! -
    - -

    You can also process the results of a query one row at a time -by specifying the name of an array variable and a script following -the SQL code. For each row of the query result, the values of all -columns will be inserted into the array variable and the script will -be executed. For instance:

    - -
    -db1 eval {SELECT * FROM t1 ORDER BY a} values {
    -    parray values
    -    puts ""
    -}
    -
    - -

    This last code will give the following output:

    - -
    -values(*) = a b
    -values(a) = 1
    -values(b) = hello

    - -values(*) = a b
    -values(a) = 2
    -values(b) = goodbye

    - -values(*) = a b
    -values(a) = 3
    -values(b) = howdy!
    -

    - -

    -For each column in a row of the result, the name of that column -is used as an index in to array. The value of the column is stored -in the corresponding array entry. The special array index * is -used to store a list of column names in the order that they appear. -

    - -

    -If the array variable name is omitted or is the empty string, then the value of -each column is stored in a variable with the same name as the column -itself. For example: -

    - -
    -db1 eval {SELECT * FROM t1 ORDER BY a} {
    -    puts "a=$a b=$b"
    -}
    -
    - -

    -From this we get the following output -

    - -
    -a=1 b=hello
    -a=2 b=goodbye
    -a=3 b=howdy!
    -
    - -

    -Tcl variable names can appear in the SQL statement of the second argument -in any position where it is legal to put a string or number literal. The -value of the variable is substituted for the variable name. If the -variable does not exist a NULL values is used. For example: -

    - -
    -db1 eval {INSERT INTO t1 VALUES(5,$bigblob)} -
    - -

    -Note that it is not necessary to quote the $bigblob value. That happens -automatically. If $bigblob is a large string or binary object, this -technique is not only easier to write, it is also much more efficient -since it avoids making a copy of the content of $bigblob. -

    - -} - -############################################################################## -METHOD complete { - -

    -The "complete" method takes a string of supposed SQL as its only argument. -It returns TRUE if the string is a complete statement of SQL and FALSE if -there is more to be entered.

    - -

    The "complete" method is useful when building interactive applications -in order to know when the user has finished entering a line of SQL code. -This is really just an interface to the sqlite3_complete() C -function. Refer to the C/C++ interface -specification for additional information.

    -} - -############################################################################## -METHOD copy { - -

    -The "copy" method copies data from a file into a table. -It returns the number of rows processed successfully from the file. -The syntax of the copy method looks like this:

    - -
    -dbcmd  copy  conflict-algorithm -  table-name   file-name  -    ?column-separator ? -  ?null-indicator? -
    - -

    Conflict-alogrithm must be one of the SQLite conflict algorithms for -the INSERT statement: rollback, abort, -fail,ignore, or replace. See the SQLite Language -section for ON CONFLICT for more information. -The conflict-algorithm must be specified in lower case. -

    - -

    Table-name must already exists as a table. File-name must exist, and -each row must contain the same number of columns as defined in the table. -If a line in the file contains more or less than the number of columns defined, -the copy method rollbacks any inserts, and returns an error.

    - -

    Column-separator is an optional column separator string. The default is -the ASCII tab character \t.

    - -

    Null-indicator is an optional string that indicates a column value is null. -The default is an empty string. Note that column-separator and -null-indicator are optional positional arguments; if null-indicator -is specified, a column-separator argument must be specifed and -precede the null-indicator argument.

    - -

    The copy method implements similar functionality to the .import -SQLite shell command. -The SQLite 2.x COPY statement -(using the PostgreSQL COPY file format) -can be implemented with this method as:

    - -
    -dbcmd  copy  $conflictalgo -  $tablename   $filename  -    \t  -  \\N -
    - -} - -############################################################################## -METHOD timeout { - -

    The "timeout" method is used to control how long the SQLite library -will wait for locks to clear before giving up on a database transaction. -The default timeout is 0 millisecond. (In other words, the default behavior -is not to wait at all.)

    - -

    The SQLite database allows multiple simultaneous -readers or a single writer but not both. If any process is writing to -the database no other process is allows to read or write. If any process -is reading the database other processes are allowed to read but not write. -The entire database shared a single lock.

    - -

    When SQLite tries to open a database and finds that it is locked, it -can optionally delay for a short while and try to open the file again. -This process repeats until the query times out and SQLite returns a -failure. The timeout is adjustable. It is set to 0 by default so that -if the database is locked, the SQL statement fails immediately. But you -can use the "timeout" method to change the timeout value to a positive -number. For example:

    - -
    db1 timeout 2000
    - -

    The argument to the timeout method is the maximum number of milliseconds -to wait for the lock to clear. So in the example above, the maximum delay -would be 2 seconds.

    -} - -############################################################################## -METHOD busy { - -

    The "busy" method, like "timeout", only comes into play when the -database is locked. But the "busy" method gives the programmer much more -control over what action to take. The "busy" method specifies a callback -Tcl procedure that is invoked whenever SQLite tries to open a locked -database. This callback can do whatever is desired. Presumably, the -callback will do some other useful work for a short while (such as service -GUI events) then return -so that the lock can be tried again. The callback procedure should -return "0" if it wants SQLite to try again to open the database and -should return "1" if it wants SQLite to abandon the current operation. -} - -############################################################################## -METHOD last_insert_rowid { - -

    The "last_insert_rowid" method returns an integer which is the ROWID -of the most recently inserted database row.

    -} - -############################################################################## -METHOD function { - -

    The "function" method registers new SQL functions with the SQLite engine. -The arguments are the name of the new SQL function and a TCL command that -implements that function. Arguments to the function are appended to the -TCL command before it is invoked.

    - -

    -The following example creates a new SQL function named "hex" that converts -its numeric argument in to a hexadecimal encoded string: -

    - -
    -db function hex {format 0x%X} -
    - -} - -############################################################################## -METHOD onecolumn { - -

    The "onecolumn" method works like "eval" in that it evaluates the -SQL query statement given as its argument. The difference is that -"onecolumn" returns a single element which is the first column of the -first row of the query result.

    - -

    This is a convenience method. It saves the user from having to -do a "[lindex ... 0]" on the results of an "eval" -in order to extract a single column result.

    -} - -############################################################################## -METHOD changes { - -

    The "changes" method returns an integer which is the number of rows -in the database that were inserted, deleted, and/or modified by the most -recent "eval" method.

    -} - -############################################################################## -METHOD total_changes { - -

    The "total_changes" method returns an integer which is the number of rows -in the database that were inserted, deleted, and/or modified since the -current database connection was first opened.

    -} - -############################################################################## -METHOD authorizer { - -

    The "authorizer" method provides access to the sqlite3_set_authorizer -C/C++ interface. The argument to authorizer is the name of a procedure that -is called when SQL statements are being compiled in order to authorize -certain operations. The callback procedure takes 5 arguments which describe -the operation being coded. If the callback returns the text string -"SQLITE_OK", then the operation is allowed. If it returns "SQLITE_IGNORE", -then the operation is silently disabled. If the return is "SQLITE_DENY" -then the compilation fails with an error. -

    - -

    If the argument is an empty string then the authorizer is disabled. -If the argument is omitted, then the current authorizer is returned.

    -} - -############################################################################## -METHOD progress { - -

    This method registers a callback that is invoked periodically during -query processing. There are two arguments: the number of SQLite virtual -machine opcodes between invocations, and the TCL command to invoke. -Setting the progress callback to an empty string disables it.

    - -

    The progress callback can be used to display the status of a lengthy -query or to process GUI events during a lengthy query.

    -} - - -############################################################################## -METHOD collate { - -

    This method registers new text collating sequences. There are -two arguments: the name of the collating sequence and the name of a -TCL procedure that implements a comparison function for the collating -sequence. -

    - -

    For example, the following code implements a collating sequence called -"NOCASE" that sorts in text order without regard to case: -

    - -
    -proc nocase_compare {a b} {
    -    return [string compare [string tolower $a] [string tolower $b]]
    -}
    -db collate NOCASE nocase_compare
    -
    -} - -############################################################################## -METHOD collation_needed { - -

    This method registers a callback routine that is invoked when the SQLite -engine needs a particular collating sequence but does not have that -collating sequence registered. The callback can register the collating -sequence. The callback is invoked with a single parameter which is the -name of the needed collating sequence.

    -} - -############################################################################## -METHOD commit_hook { - -

    This method registers a callback routine that is invoked just before -SQLite tries to commit changes to a database. If the callback throws -an exception or returns a non-zero result, then the transaction rolls back -rather than commit.

    -} - -############################################################################## -METHOD errorcode { - -

    This method returns the numeric error code that resulted from the most -recent SQLite operation.

    -} - -############################################################################## -METHOD trace { - -

    The "trace" method registers a callback that is invoked as each SQL -statement is compiled. The text of the SQL is appended as a single string -to the command before it is invoked. This can be used (for example) to -keep a log of all SQL operations that an application performs. -

    -} - - -footer $rcsid diff --git a/sqlite/www/vdbe.tcl b/sqlite/www/vdbe.tcl deleted file mode 100644 index a9341ba..0000000 --- a/sqlite/www/vdbe.tcl +++ /dev/null @@ -1,1983 +0,0 @@ -# -# Run this Tcl script to generate the vdbe.html file. -# -set rcsid {$Id: vdbe.tcl,v 1.13 2004/11/10 05:48:57 danielk1977 Exp $} -source common.tcl -header {The Virtual Database Engine of SQLite} -puts { -

    The Virtual Database Engine of SQLite

    - -
    -This document describes the virtual machine used in SQLite version 2.8.0. -
    -} - -puts { -

    If you want to know how the SQLite library works internally, -you need to begin with a solid understanding of the Virtual Database -Engine or VDBE. The VDBE occurs right in the middle of the -processing stream (see the architecture diagram) -and so it seems to touch most parts of the library. Even -parts of the code that do not directly interact with the VDBE -are usually in a supporting role. The VDBE really is the heart of -SQLite.

    - -

    This article is a brief introduction to how the VDBE -works and in particular how the various VDBE instructions -(documented here) work together -to do useful things with the database. The style is tutorial, -beginning with simple tasks and working toward solving more -complex problems. Along the way we will visit most -submodules in the SQLite library. After completeing this tutorial, -you should have a pretty good understanding of how SQLite works -and will be ready to begin studying the actual source code.

    - -

    Preliminaries

    - -

    The VDBE implements a virtual computer that runs a program in -its virtual machine language. The goal of each program is to -interrogate or change the database. Toward this end, the machine -language that the VDBE implements is specifically designed to -search, read, and modify databases.

    - -

    Each instruction of the VDBE language contains an opcode and -three operands labeled P1, P2, and P3. Operand P1 is an arbitrary -integer. P2 is a non-negative integer. P3 is a pointer to a data -structure or null-terminated string, possibly null. Only a few VDBE -instructions use all three operands. Many instructions use only -one or two operands. A significant number of instructions use -no operands at all but instead take their data and store their results -on the execution stack. The details of what each instruction -does and which operands it uses are described in the separate -opcode description document.

    - -

    A VDBE program begins -execution on instruction 0 and continues with successive instructions -until it either (1) encounters a fatal error, (2) executes a -Halt instruction, or (3) advances the program counter past the -last instruction of the program. When the VDBE completes execution, -all open database cursors are closed, all memory is freed, and -everything is popped from the stack. -So there are never any worries about memory leaks or -undeallocated resources.

    - -

    If you have done any assembly language programming or have -worked with any kind of abstract machine before, all of these -details should be familiar to you. So let's jump right in and -start looking as some code.

    - - -

    Inserting Records Into The Database

    - -

    We begin with a problem that can be solved using a VDBE program -that is only a few instructions long. Suppose we have an SQL -table that was created like this:

    - -
    -CREATE TABLE examp(one text, two int);
    -
    - -

    In words, we have a database table named "examp" that has two -columns of data named "one" and "two". Now suppose we want to insert a single -record into this table. Like this:

    - -
    -INSERT INTO examp VALUES('Hello, World!',99);
    -
    - -

    We can see the VDBE program that SQLite uses to implement this -INSERT using the sqlite command-line utility. First start -up sqlite on a new, empty database, then create the table. -Next change the output format of sqlite to a form that -is designed to work with VDBE program dumps by entering the -".explain" command. -Finally, enter the INSERT statement shown above, but precede the -INSERT with the special keyword "EXPLAIN". The EXPLAIN keyword -will cause sqlite to print the VDBE program rather than -execute it. We have:

    -} -proc Code {body} { - puts {
    } - regsub -all {&} [string trim $body] {\&} body - regsub -all {>} $body {\>} body - regsub -all {<} $body {\<} body - regsub -all {\(\(\(} $body {} body - regsub -all {\)\)\)} $body {} body - regsub -all { } $body {\ } body - regsub -all \n $body
    \n body - puts $body - puts {
    } -} - -Code { -$ (((sqlite test_database_1))) -sqlite> (((CREATE TABLE examp(one text, two int);))) -sqlite> (((.explain))) -sqlite> (((EXPLAIN INSERT INTO examp VALUES('Hello, World!',99);))) -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 Transaction 0 0 -1 VerifyCookie 0 81 -2 Transaction 1 0 -3 Integer 0 0 -4 OpenWrite 0 3 examp -5 NewRecno 0 0 -6 String 0 0 Hello, World! -7 Integer 99 0 99 -8 MakeRecord 2 0 -9 PutIntKey 0 1 -10 Close 0 0 -11 Commit 0 0 -12 Halt 0 0 -} - -puts {

    As you can see above, our simple insert statement is -implemented in 12 instructions. The first 3 and last 2 instructions are -a standard prologue and epilogue, so the real work is done in the middle -7 instructions. There are no jumps, so the program executes once through -from top to bottom. Let's now look at each instruction in detail.

    -} - -Code { -0 Transaction 0 0 -1 VerifyCookie 0 81 -2 Transaction 1 0 -} -puts { -

    The instruction Transaction -begins a transaction. The transaction ends when a Commit or Rollback -opcode is encountered. P1 is the index of the database file on which -the transaction is started. Index 0 is the main database file. A write -lock is obtained on the database file when a transaction is started. -No other process can read or write the file while the transaction is -underway. Starting a transaction also creates a rollback journal. A -transaction must be started before any changes can be made to the -database.

    - -

    The instruction VerifyCookie -checks cookie 0 (the database schema version) to make sure it is equal -to P2 (the value obtained when the database schema was last read). -P1 is the database number (0 for the main database). This is done to -make sure the database schema hasn't been changed by another thread, in -which case it has to be reread.

    - -

    The second Transaction -instruction begins a transaction and starts a rollback journal for -database 1, the database used for temporary tables.

    -} - -proc stack args { - puts "
    " - foreach elem $args { - puts "" - } - puts "
    $elem
    " -} - -Code { -3 Integer 0 0 -4 OpenWrite 0 3 examp -} -puts { -

    The instruction Integer pushes -the integer value P1 (0) onto the stack. Here 0 is the number of the -database to use in the following OpenWrite instruction. If P3 is not -NULL then it is a string representation of the same integer. Afterwards -the stack looks like this:

    -} -stack {(integer) 0} - -puts { -

    The instruction OpenWrite opens -a new read/write cursor with handle P1 (0 in this case) on table "examp", -whose root page is P2 (3, in this database file). Cursor handles can be -any non-negative integer. But the VDBE allocates cursors in an array -with the size of the array being one more than the largest cursor. So -to conserve memory, it is best to use handles beginning with zero and -working upward consecutively. Here P3 ("examp") is the name of the -table being opened, but this is unused, and only generated to make the -code easier to read. This instruction pops the database number to use -(0, the main database) from the top of the stack, so afterwards the -stack is empty again.

    -} - -Code { -5 NewRecno 0 0 -} -puts { -

    The instruction NewRecno creates -a new integer record number for the table pointed to by cursor P1. The -record number is one not currently used as a key in the table. The new -record number is pushed onto the stack. Afterwards the stack looks like -this:

    -} -stack {(integer) new record key} - -Code { -6 String 0 0 Hello, World! -} -puts { -

    The instruction String pushes its -P3 operand onto the stack. Afterwards the stack looks like this:

    -} -stack {(string) "Hello, World!"} \ - {(integer) new record key} - -Code { -7 Integer 99 0 99 -} -puts { -

    The instruction Integer pushes -its P1 operand (99) onto the stack. Afterwards the stack looks like -this:

    -} -stack {(integer) 99} \ - {(string) "Hello, World!"} \ - {(integer) new record key} - -Code { -8 MakeRecord 2 0 -} -puts { -

    The instruction MakeRecord pops -the top P1 elements off the stack (2 in this case) and converts them into -the binary format used for storing records in a database file. -(See the file format description for -details.) The new record generated by the MakeRecord instruction is -pushed back onto the stack. Afterwards the stack looks like this:

    - -} -stack {(record) "Hello, World!", 99} \ - {(integer) new record key} - -Code { -9 PutIntKey 0 1 -} -puts { -

    The instruction PutIntKey uses -the top 2 stack entries to write an entry into the table pointed to by -cursor P1. A new entry is created if it doesn't already exist or the -data for an existing entry is overwritten. The record data is the top -stack entry, and the key is the next entry down. The stack is popped -twice by this instruction. Because operand P2 is 1 the row change count -is incremented and the rowid is stored for subsequent return by the -sqlite_last_insert_rowid() function. If P2 is 0 the row change count is -unmodified. This instruction is where the insert actually occurs.

    -} - -Code { -10 Close 0 0 -} -puts { -

    The instruction Close closes a -cursor previously opened as P1 (0, the only open cursor). If P1 is not -currently open, this instruction is a no-op.

    -} - -Code { -11 Commit 0 0 -} -puts { -

    The instruction Commit causes all -modifications to the database that have been made since the last -Transaction to actually take effect. No additional modifications are -allowed until another transaction is started. The Commit instruction -deletes the journal file and releases the write lock on the database. -A read lock continues to be held if there are still cursors open.

    -} - -Code { -12 Halt 0 0 -} -puts { -

    The instruction Halt causes the VDBE -engine to exit immediately. All open cursors, Lists, Sorts, etc are -closed automatically. P1 is the result code returned by sqlite_exec(). -For a normal halt, this should be SQLITE_OK (0). For errors, it can be -some other value. The operand P2 is only used when there is an error. -There is an implied "Halt 0 0 0" instruction at the end of every -program, which the VDBE appends when it prepares a program to run.

    - - - -

    Tracing VDBE Program Execution

    - -

    If the SQLite library is compiled without the NDEBUG preprocessor -macro, then the PRAGMA vdbe_trace - causes the VDBE to trace the execution of programs. Though this -feature was originally intended for testing and debugging, it can also -be useful in learning about how the VDBE operates. -Use "PRAGMA vdbe_trace=ON;" to turn tracing on and -"PRAGMA vdbe_trace=OFF" to turn tracing back off. -Like this:

    -} - -Code { -sqlite> (((PRAGMA vdbe_trace=ON;))) - 0 Halt 0 0 -sqlite> (((INSERT INTO examp VALUES('Hello, World!',99);))) - 0 Transaction 0 0 - 1 VerifyCookie 0 81 - 2 Transaction 1 0 - 3 Integer 0 0 -Stack: i:0 - 4 OpenWrite 0 3 examp - 5 NewRecno 0 0 -Stack: i:2 - 6 String 0 0 Hello, World! -Stack: t[Hello,.World!] i:2 - 7 Integer 99 0 99 -Stack: si:99 t[Hello,.World!] i:2 - 8 MakeRecord 2 0 -Stack: s[...Hello,.World!.99] i:2 - 9 PutIntKey 0 1 - 10 Close 0 0 - 11 Commit 0 0 - 12 Halt 0 0 -} - -puts { -

    With tracing mode on, the VDBE prints each instruction prior -to executing it. After the instruction is executed, the top few -entries in the stack are displayed. The stack display is omitted -if the stack is empty.

    - -

    On the stack display, most entries are shown with a prefix -that tells the datatype of that stack entry. Integers begin -with "i:". Floating point values begin with "r:". -(The "r" stands for "real-number".) Strings begin with either -"s:", "t:", "e:" or "z:". -The difference among the string prefixes is caused by how their -memory is allocated. The z: strings are stored in memory obtained -from malloc(). The t: strings are statically allocated. -The e: strings are ephemeral. All other strings have the s: prefix. -This doesn't make any difference to you, -the observer, but it is vitally important to the VDBE since the -z: strings need to be passed to free() when they are -popped to avoid a memory leak. Note that only the first 10 -characters of string values are displayed and that binary -values (such as the result of the MakeRecord instruction) are -treated as strings. The only other datatype that can be stored -on the VDBE stack is a NULL, which is display without prefix -as simply "NULL". If an integer has been placed on the -stack as both an integer and a string, its prefix is "si:". - - - -

    Simple Queries

    - -

    At this point, you should understand the basics of how the VDBE -writes to a database. Now let's look at how it does queries. -We will use the following simple SELECT statement as our example:

    - -
    -SELECT * FROM examp;
    -
    - -

    The VDBE program generated for this SQL statement is as follows:

    -} - -Code { -sqlite> (((EXPLAIN SELECT * FROM examp;))) -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 ColumnName 0 0 one -1 ColumnName 1 0 two -2 Integer 0 0 -3 OpenRead 0 3 examp -4 VerifyCookie 0 81 -5 Rewind 0 10 -6 Column 0 0 -7 Column 0 1 -8 Callback 2 0 -9 Next 0 6 -10 Close 0 0 -11 Halt 0 0 -} - -puts { -

    Before we begin looking at this problem, let's briefly review -how queries work in SQLite so that we will know what we are trying -to accomplish. For each row in the result of a query, -SQLite will invoke a callback function with the following -prototype:

    - -
    -int Callback(void *pUserData, int nColumn, char *azData[], char *azColumnName[]);
    -
    - -

    The SQLite library supplies the VDBE with a pointer to the callback function -and the pUserData pointer. (Both the callback and the user data were -originally passed in as arguments to the sqlite_exec() API function.) -The job of the VDBE is to -come up with values for nColumn, azData[], -and azColumnName[]. -nColumn is the number of columns in the results, of course. -azColumnName[] is an array of strings where each string is the name -of one of the result columns. azData[] is an array of strings holding -the actual data.

    -} - -Code { -0 ColumnName 0 0 one -1 ColumnName 1 0 two -} -puts { -

    The first two instructions in the VDBE program for our query are -concerned with setting up values for azColumn. -The ColumnName instructions tell -the VDBE what values to fill in for each element of the azColumnName[] -array. Every query will begin with one ColumnName instruction for each -column in the result, and there will be a matching Column instruction for -each one later in the query. -

    -} - -Code { -2 Integer 0 0 -3 OpenRead 0 3 examp -4 VerifyCookie 0 81 -} -puts { -

    Instructions 2 and 3 open a read cursor on the database table that is -to be queried. This works the same as the OpenWrite instruction in the -INSERT example except that the cursor is opened for reading this time -instead of for writing. Instruction 4 verifies the database schema as -in the INSERT example.

    -} - -Code { -5 Rewind 0 10 -} -puts { -

    The Rewind instruction initializes -a loop that iterates over the "examp" table. It rewinds the cursor P1 -to the first entry in its table. This is required by the the Column and -Next instructions, which use the cursor to iterate through the table. -If the table is empty, then jump to P2 (10), which is the instruction just -past the loop. If the table is not empty, fall through to the following -instruction at 6, which is the beginning of the loop body.

    -} - -Code { -6 Column 0 0 -7 Column 0 1 -8 Callback 2 0 -} -puts { -

    The instructions 6 through 8 form the body of the loop that will -execute once for each record in the database file. - -The Column instructions at addresses 6 -and 7 each take the P2-th column from the P1-th cursor and push it onto -the stack. In this example, the first Column instruction is pushing the -value for the column "one" onto the stack and the second Column -instruction is pushing the value for column "two". - -The Callback instruction at address 8 -invokes the callback() function. The P1 operand to Callback becomes the -value for nColumn. The Callback instruction pops P1 values from -the stack and uses them to fill the azData[] array.

    -} - -Code { -9 Next 0 6 -} -puts { -

    The instruction at address 9 implements the branching part of the -loop. Together with the Rewind at address 5 it forms the loop logic. -This is a key concept that you should pay close attention to. -The Next instruction advances the cursor -P1 to the next record. If the cursor advance was successful, then jump -immediately to P2 (6, the beginning of the loop body). If the cursor -was at the end, then fall through to the following instruction, which -ends the loop.

    -} - -Code { -10 Close 0 0 -11 Halt 0 0 -} -puts { -

    The Close instruction at the end of the program closes the -cursor that points into the table "examp". It is not really necessary -to call Close here since all cursors will be automatically closed -by the VDBE when the program halts. But we needed an instruction -for the Rewind to jump to so we might as well go ahead and have that -instruction do something useful. -The Halt instruction ends the VDBE program.

    - -

    Note that the program for this SELECT query didn't contain the -Transaction and Commit instructions used in the INSERT example. Because -the SELECT is a read operation that doesn't alter the database, it -doesn't require a transaction.

    -} - - -puts { - -

    A Slightly More Complex Query

    - -

    The key points of the previous example were the use of the Callback -instruction to invoke the callback function, and the use of the Next -instruction to implement a loop over all records of the database file. -This example attempts to drive home those ideas by demonstrating a -slightly more complex query that involves more columns of -output, some of which are computed values, and a WHERE clause that -limits which records actually make it to the callback function. -Consider this query:

    - -
    -SELECT one, two, one || two AS 'both'
    -FROM examp
    -WHERE one LIKE 'H%'
    -
    - -

    This query is perhaps a bit contrived, but it does serve to -illustrate our points. The result will have three column with -names "one", "two", and "both". The first two columns are direct -copies of the two columns in the table and the third result -column is a string formed by concatenating the first and -second columns of the table. -Finally, the -WHERE clause says that we will only chose rows for the -results where the "one" column begins with an "H". -Here is what the VDBE program looks like for this query:

    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 ColumnName 0 0 one -1 ColumnName 1 0 two -2 ColumnName 2 0 both -3 Integer 0 0 -4 OpenRead 0 3 examp -5 VerifyCookie 0 81 -6 Rewind 0 18 -7 String 0 0 H% -8 Column 0 0 -9 Function 2 0 ptr(0x7f1ac0) -10 IfNot 1 17 -11 Column 0 0 -12 Column 0 1 -13 Column 0 0 -14 Column 0 1 -15 Concat 2 0 -16 Callback 3 0 -17 Next 0 7 -18 Close 0 0 -19 Halt 0 0 -} - -puts { -

    Except for the WHERE clause, the structure of the program for -this example is very much like the prior example, just with an -extra column. There are now 3 columns, instead of 2 as before, -and there are three ColumnName instructions. -A cursor is opened using the OpenRead instruction, just like in the -prior example. The Rewind instruction at address 6 and the -Next at address 17 form a loop over all records of the table. -The Close instruction at the end is there to give the -Rewind instruction something to jump to when it is done. All of -this is just like in the first query demonstration.

    - -

    The Callback instruction in this example has to generate -data for three result columns instead of two, but is otherwise -the same as in the first query. When the Callback instruction -is invoked, the left-most column of the result should be -the lowest in the stack and the right-most result column should -be the top of the stack. We can see the stack being set up -this way at addresses 11 through 15. The Column instructions at -11 and 12 push the values for the first two columns in the result. -The two Column instructions at 13 and 14 pull in the values needed -to compute the third result column and the Concat instruction at -15 joins them together into a single entry on the stack.

    - -

    The only thing that is really new about the current example -is the WHERE clause which is implemented by instructions at -addresses 7 through 10. Instructions at address 7 and 8 push -onto the stack the value of the "one" column from the table -and the literal string "H%". -The Function instruction at address 9 -pops these two values from the stack and pushes the result of the LIKE() -function back onto the stack. -The IfNot instruction pops the top stack -value and causes an immediate jump forward to the Next instruction if the -top value was false (not not like the literal string "H%"). -Taking this jump effectively skips the callback, which is the whole point -of the WHERE clause. If the result -of the comparison is true, the jump is not taken and control -falls through to the Callback instruction below.

    - -

    Notice how the LIKE operator is implemented. It is a user-defined -function in SQLite, so the address of its function definition is -specified in P3. The operand P1 is the number of function arguments for -it to take from the stack. In this case the LIKE() function takes 2 -arguments. The arguments are taken off the stack in reverse order -(right-to-left), so the pattern to match is the top stack element, and -the next element is the data to compare. The return value is pushed -onto the stack.

    - - - -

    A Template For SELECT Programs

    - -

    The first two query examples illustrate a kind of template that -every SELECT program will follow. Basically, we have:

    - -

    -

      -
    1. Initialize the azColumnName[] array for the callback.
    2. -
    3. Open a cursor into the table to be queried.
    4. -
    5. For each record in the table, do: -
        -
      1. If the WHERE clause evaluates to FALSE, then skip the steps that - follow and continue to the next record.
      2. -
      3. Compute all columns for the current row of the result.
      4. -
      5. Invoke the callback function for the current row of the result.
      6. -
      -
    6. Close the cursor.
    7. -
    -

    - -

    This template will be expanded considerably as we consider -additional complications such as joins, compound selects, using -indices to speed the search, sorting, and aggregate functions -with and without GROUP BY and HAVING clauses. -But the same basic ideas will continue to apply.

    - -

    UPDATE And DELETE Statements

    - -

    The UPDATE and DELETE statements are coded using a template -that is very similar to the SELECT statement template. The main -difference, of course, is that the end action is to modify the -database rather than invoke a callback function. Because it modifies -the database it will also use transactions. Let's begin -by looking at a DELETE statement:

    - -
    -DELETE FROM examp WHERE two<50;
    -
    - -

    This DELETE statement will remove every record from the "examp" -table where the "two" column is less than 50. -The code generated to do this is as follows:

    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 Transaction 1 0 -1 Transaction 0 0 -2 VerifyCookie 0 178 -3 Integer 0 0 -4 OpenRead 0 3 examp -5 Rewind 0 12 -6 Column 0 1 -7 Integer 50 0 50 -8 Ge 1 11 -9 Recno 0 0 -10 ListWrite 0 0 -11 Next 0 6 -12 Close 0 0 -13 ListRewind 0 0 -14 Integer 0 0 -15 OpenWrite 0 3 -16 ListRead 0 20 -17 NotExists 0 19 -18 Delete 0 1 -19 Goto 0 16 -20 ListReset 0 0 -21 Close 0 0 -22 Commit 0 0 -23 Halt 0 0 -} - -puts { -

    Here is what the program must do. First it has to locate all of -the records in the table "examp" that are to be deleted. This is -done using a loop very much like the loop used in the SELECT examples -above. Once all records have been located, then we can go back through -and delete them one by one. Note that we cannot delete each record -as soon as we find it. We have to locate all records first, then -go back and delete them. This is because the SQLite database -backend might change the scan order after a delete operation. -And if the scan -order changes in the middle of the scan, some records might be -visited more than once and other records might not be visited at all.

    - -

    So the implemention of DELETE is really in two loops. The first loop -(instructions 5 through 11) locates the records that are to be deleted -and saves their keys onto a temporary list, and the second loop -(instructions 16 through 19) uses the key list to delete the records one -by one.

    -} - - -Code { -0 Transaction 1 0 -1 Transaction 0 0 -2 VerifyCookie 0 178 -3 Integer 0 0 -4 OpenRead 0 3 examp -} -puts { -

    Instructions 0 though 4 are as in the INSERT example. They start -transactions for the main and temporary databases, verify the database -schema for the main database, and open a read cursor on the table -"examp". Notice that the cursor is opened for reading, not writing. At -this stage of the program we are only going to be scanning the table, -not changing it. We will reopen the same table for writing later, at -instruction 15.

    -} - -Code { -5 Rewind 0 12 -} -puts { -

    As in the SELECT example, the Rewind -instruction rewinds the cursor to the beginning of the table, readying -it for use in the loop body.

    -} - -Code { -6 Column 0 1 -7 Integer 50 0 50 -8 Ge 1 11 -} -puts { -

    The WHERE clause is implemented by instructions 6 through 8. -The job of the where clause is to skip the ListWrite if the WHERE -condition is false. To this end, it jumps ahead to the Next instruction -if the "two" column (extracted by the Column instruction) is -greater than or equal to 50.

    - -

    As before, the Column instruction uses cursor P1 and pushes the data -record in column P2 (1, column "two") onto the stack. The Integer -instruction pushes the value 50 onto the top of the stack. After these -two instructions the stack looks like:

    -} -stack {(integer) 50} \ - {(record) current record for column "two" } - -puts { -

    The Ge operator compares the top two -elements on the stack, pops them, and then branches based on the result -of the comparison. If the second element is >= the top element, then -jump to address P2 (the Next instruction at the end of the loop). -Because P1 is true, if either operand is NULL (and thus the result is -NULL) then take the jump. If we don't jump, just advance to the next -instruction.

    -} - -Code { -9 Recno 0 0 -10 ListWrite 0 0 -} -puts { -

    The Recno instruction pushes onto the -stack an integer which is the first 4 bytes of the the key to the current -entry in a sequential scan of the table pointed to by cursor P1. -The ListWrite instruction writes the -integer on the top of the stack into a temporary storage list and pops -the top element. This is the important work of this loop, to store the -keys of the records to be deleted so we can delete them in the second -loop. After this ListWrite instruction the stack is empty again.

    -} - -Code { -11 Next 0 6 -12 Close 0 0 -} -puts { -

    The Next instruction increments the cursor to point to the next -element in the table pointed to by cursor P0, and if it was successful -branches to P2 (6, the beginning of the loop body). The Close -instruction closes cursor P1. It doesn't affect the temporary storage -list because it isn't associated with cursor P1; it is instead a global -working list (which can be saved with ListPush).

    -} - -Code { -13 ListRewind 0 0 -} -puts { -

    The ListRewind instruction -rewinds the temporary storage list to the beginning. This prepares it -for use in the second loop.

    -} - -Code { -14 Integer 0 0 -15 OpenWrite 0 3 -} -puts { -

    As in the INSERT example, we push the database number P1 (0, the main -database) onto the stack and use OpenWrite to open the cursor P1 on table -P2 (base page 3, "examp") for modification.

    -} - -Code { -16 ListRead 0 20 -17 NotExists 0 19 -18 Delete 0 1 -19 Goto 0 16 -} -puts { -

    This loop does the actual deleting. It is organized differently from -the one in the UPDATE example. The ListRead instruction plays the role -that the Next did in the INSERT loop, but because it jumps to P2 on -failure, and Next jumps on success, we put it at the start of the loop -instead of the end. This means that we have to put a Goto at the end of -the loop to jump back to the the loop test at the beginning. So this -loop has the form of a C while(){...} loop, while the loop in the INSERT -example had the form of a do{...}while() loop. The Delete instruction -fills the role that the callback function did in the preceding examples. -

    -

    The ListRead instruction reads an -element from the temporary storage list and pushes it onto the stack. -If this was successful, it continues to the next instruction. If this -fails because the list is empty, it branches to P2, which is the -instruction just after the loop. Afterwards the stack looks like:

    -} -stack {(integer) key for current record} - -puts { -

    Notice the similarity between the ListRead and Next instructions. -Both operations work according to this rule: -

    -
    -Push the next "thing" onto the stack and fall through OR jump to P2, -depending on whether or not there is a next "thing" to push. -
    -

    One difference between Next and ListRead is their idea of a "thing". -The "things" for the Next instruction are records in a database file. -"Things" for ListRead are integer keys in a list. Another difference -is whether to jump or fall through if there is no next "thing". In this -case, Next falls through, and ListRead jumps. Later on, we will see -other looping instructions (NextIdx and SortNext) that operate using the -same principle.

    - -

    The NotExists instruction pops -the top stack element and uses it as an integer key. If a record with -that key does not exist in table P1, then jump to P2. If a record does -exist, then fall thru to the next instruction. In this case P2 takes -us to the Goto at the end of the loop, which jumps back to the ListRead -at the beginning. This could have been coded to have P2 be 16, the -ListRead at the start of the loop, but the SQLite parser which generated -this code didn't make that optimization.

    -

    The Delete does the work of this -loop; it pops an integer key off the stack (placed there by the -preceding ListRead) and deletes the record of cursor P1 that has that key. -Because P2 is true, the row change counter is incremented.

    -

    The Goto jumps back to the beginning -of the loop. This is the end of the loop.

    -} - -Code { -20 ListReset 0 0 -21 Close 0 0 -22 Commit 0 0 -23 Halt 0 0 -} -puts { -

    This block of instruction cleans up the VDBE program. Three of these -instructions aren't really required, but are generated by the SQLite -parser from its code templates, which are designed to handle more -complicated cases.

    -

    The ListReset instruction empties -the temporary storage list. This list is emptied automatically when the -VDBE program terminates, so it isn't necessary in this case. The Close -instruction closes the cursor P1. Again, this is done by the VDBE -engine when it is finished running this program. The Commit ends the -current transaction successfully, and causes all changes that occurred -in this transaction to be saved to the database. The final Halt is also -unneccessary, since it is added to every VDBE program when it is -prepared to run.

    - - -

    UPDATE statements work very much like DELETE statements except -that instead of deleting the record they replace it with a new one. -Consider this example: -

    - -
    -UPDATE examp SET one= '(' || one || ')' WHERE two < 50;
    -
    - -

    Instead of deleting records where the "two" column is less than -50, this statement just puts the "one" column in parentheses -The VDBE program to implement this statement follows:

    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 Transaction 1 0 -1 Transaction 0 0 -2 VerifyCookie 0 178 -3 Integer 0 0 -4 OpenRead 0 3 examp -5 Rewind 0 12 -6 Column 0 1 -7 Integer 50 0 50 -8 Ge 1 11 -9 Recno 0 0 -10 ListWrite 0 0 -11 Next 0 6 -12 Close 0 0 -13 Integer 0 0 -14 OpenWrite 0 3 -15 ListRewind 0 0 -16 ListRead 0 28 -17 Dup 0 0 -18 NotExists 0 16 -19 String 0 0 ( -20 Column 0 0 -21 Concat 2 0 -22 String 0 0 ) -23 Concat 2 0 -24 Column 0 1 -25 MakeRecord 2 0 -26 PutIntKey 0 1 -27 Goto 0 16 -28 ListReset 0 0 -29 Close 0 0 -30 Commit 0 0 -31 Halt 0 0 -} - -puts { -

    This program is essentially the same as the DELETE program except -that the body of the second loop has been replace by a sequence of -instructions (at addresses 17 through 26) that update the record rather -than delete it. Most of this instruction sequence should already be -familiar to you, but there are a couple of minor twists so we will go -over it briefly. Also note that the order of some of the instructions -before and after the 2nd loop has changed. This is just the way the -SQLite parser chose to output the code using a different template.

    - -

    As we enter the interior of the second loop (at instruction 17) -the stack contains a single integer which is the key of the -record we want to modify. We are going to need to use this -key twice: once to fetch the old value of the record and -a second time to write back the revised record. So the first instruction -is a Dup to make a duplicate of the key on the top of the stack. The -Dup instruction will duplicate any element of the stack, not just the top -element. You specify which element to duplication using the -P1 operand. When P1 is 0, the top of the stack is duplicated. -When P1 is 1, the next element down on the stack duplication. -And so forth.

    - -

    After duplicating the key, the next instruction, NotExists, -pops the stack once and uses the value popped as a key to -check the existence of a record in the database file. If there is no record -for this key, it jumps back to the ListRead to get another key.

    - -

    Instructions 19 through 25 construct a new database record -that will be used to replace the existing record. This is -the same kind of code that we saw -in the description of INSERT and will not be described further. -After instruction 25 executes, the stack looks like this:

    -} - -stack {(record) new data record} {(integer) key} - -puts { -

    The PutIntKey instruction (also described -during the discussion about INSERT) writes an entry into the -database file whose data is the top of the stack and whose key -is the next on the stack, and then pops the stack twice. The -PutIntKey instruction will overwrite the data of an existing record -with the same key, which is what we want here. Overwriting was not -an issue with INSERT because with INSERT the key was generated -by the NewRecno instruction which is guaranteed to provide a key -that has not been used before.

    -} - -if 0 {

    (By the way, since keys must -all be unique and each key is a 32-bit integer, a single -SQLite database table can have no more than 232 -rows. Actually, the Key instruction starts to become -very inefficient as you approach this upper bound, so it -is best to keep the number of entries below 231 -or so. Surely a couple billion records will be enough for -most applications!)

    -} - -puts { -

    CREATE and DROP

    - -

    Using CREATE or DROP to create or destroy a table or index is -really the same as doing an INSERT or DELETE from the special -"sqlite_master" table, at least from the point of view of the VDBE. -The sqlite_master table is a special table that is automatically -created for every SQLite database. It looks like this:

    - -
    -CREATE TABLE sqlite_master (
    -  type      TEXT,    -- either "table" or "index"
    -  name      TEXT,    -- name of this table or index
    -  tbl_name  TEXT,    -- for indices: name of associated table
    -  sql       TEXT     -- SQL text of the original CREATE statement
    -)
    -
    - -

    Every table (except the "sqlite_master" table itself) -and every named index in an SQLite database has an entry -in the sqlite_master table. You can query this table using -a SELECT statement just like any other table. But you are -not allowed to directly change the table using UPDATE, INSERT, -or DELETE. Changes to sqlite_master have to occur using -the CREATE and DROP commands because SQLite also has to update -some of its internal data structures when tables and indices -are added or destroyed.

    - -

    But from the point of view of the VDBE, a CREATE works -pretty much like an INSERT and a DROP works like a DELETE. -When the SQLite library opens to an existing database, -the first thing it does is a SELECT to read the "sql" -columns from all entries of the sqlite_master table. -The "sql" column contains the complete SQL text of the -CREATE statement that originally generated the index or -table. This text is fed back into the SQLite parser -and used to reconstruct the -internal data structures describing the index or table.

    - -

    Using Indexes To Speed Searching

    - -

    In the example queries above, every row of the table being -queried must be loaded off of the disk and examined, even if only -a small percentage of the rows end up in the result. This can -take a long time on a big table. To speed things up, SQLite -can use an index.

    - -

    An SQLite file associates a key with some data. For an SQLite -table, the database file is set up so that the key is an integer -and the data is the information for one row of the table. -Indices in SQLite reverse this arrangement. The index key -is (some of) the information being stored and the index data -is an integer. -To access a table row that has some particular -content, we first look up the content in the index table to find -its integer index, then we use that integer to look up the -complete record in the table.

    - -

    Note that SQLite uses b-trees, which are a sorted data structure, -so indices can be used when the WHERE clause of the SELECT statement -contains tests for equality or inequality. Queries like the following -can use an index if it is available:

    - -
    -SELECT * FROM examp WHERE two==50;
    -SELECT * FROM examp WHERE two<50;
    -SELECT * FROM examp WHERE two IN (50, 100);
    -
    - -

    If there exists an index that maps the "two" column of the "examp" -table into integers, then SQLite will use that index to find the integer -keys of all rows in examp that have a value of 50 for column two, or -all rows that are less than 50, etc. -But the following queries cannot use the index:

    - -
    -SELECT * FROM examp WHERE two%50 == 10;
    -SELECT * FROM examp WHERE two&127 == 3;
    -
    - -

    Note that the SQLite parser will not always generate code to use an -index, even if it is possible to do so. The following queries will not -currently use the index:

    - -
    -SELECT * FROM examp WHERE two+10 == 50;
    -SELECT * FROM examp WHERE two==50 OR two==100;
    -
    - -

    To understand better how indices work, lets first look at how -they are created. Let's go ahead and put an index on the two -column of the examp table. We have:

    - -
    -CREATE INDEX examp_idx1 ON examp(two);
    -
    - -

    The VDBE code generated by the above statement looks like the -following:

    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 Transaction 1 0 -1 Transaction 0 0 -2 VerifyCookie 0 178 -3 Integer 0 0 -4 OpenWrite 0 2 -5 NewRecno 0 0 -6 String 0 0 index -7 String 0 0 examp_idx1 -8 String 0 0 examp -9 CreateIndex 0 0 ptr(0x791380) -10 Dup 0 0 -11 Integer 0 0 -12 OpenWrite 1 0 -13 String 0 0 CREATE INDEX examp_idx1 ON examp(tw -14 MakeRecord 5 0 -15 PutIntKey 0 0 -16 Integer 0 0 -17 OpenRead 2 3 examp -18 Rewind 2 24 -19 Recno 2 0 -20 Column 2 1 -21 MakeIdxKey 1 0 n -22 IdxPut 1 0 indexed columns are not unique -23 Next 2 19 -24 Close 2 0 -25 Close 1 0 -26 Integer 333 0 -27 SetCookie 0 0 -28 Close 0 0 -29 Commit 0 0 -30 Halt 0 0 -} - -puts { -

    Remember that every table (except sqlite_master) and every named -index has an entry in the sqlite_master table. Since we are creating -a new index, we have to add a new entry to sqlite_master. This is -handled by instructions 3 through 15. Adding an entry to sqlite_master -works just like any other INSERT statement so we will not say anymore -about it here. In this example, we want to focus on populating the -new index with valid data, which happens on instructions 16 through -23.

    -} - -Code { -16 Integer 0 0 -17 OpenRead 2 3 examp -} -puts { -

    The first thing that happens is that we open the table being -indexed for reading. In order to construct an index for a table, -we have to know what is in that table. The index has already been -opened for writing using cursor 0 by instructions 3 and 4.

    -} - -Code { -18 Rewind 2 24 -19 Recno 2 0 -20 Column 2 1 -21 MakeIdxKey 1 0 n -22 IdxPut 1 0 indexed columns are not unique -23 Next 2 19 -} -puts { -

    Instructions 18 through 23 implement a loop over every row of the -table being indexed. For each table row, we first extract the integer -key for that row using Recno in instruction 19, then get the value of -the "two" column using Column in instruction 20. -The MakeIdxKey instruction at 21 -converts data from the "two" column (which is on the top of the stack) -into a valid index key. For an index on a single column, this is -basically a no-op. But if the P1 operand to MakeIdxKey had been -greater than one multiple entries would have been popped from the stack -and converted into a single index key. -The IdxPut instruction at 22 is what -actually creates the index entry. IdxPut pops two elements from the -stack. The top of the stack is used as a key to fetch an entry from the -index table. Then the integer which was second on stack is added to the -set of integers for that index and the new record is written back to the -database file. Note -that the same index entry can store multiple integers if there -are two or more table entries with the same value for the two -column. -

    - -

    Now let's look at how this index will be used. Consider the -following query:

    - -
    -SELECT * FROM examp WHERE two==50;
    -
    - -

    SQLite generates the following VDBE code to handle this query:

    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 ColumnName 0 0 one -1 ColumnName 1 0 two -2 Integer 0 0 -3 OpenRead 0 3 examp -4 VerifyCookie 0 256 -5 Integer 0 0 -6 OpenRead 1 4 examp_idx1 -7 Integer 50 0 50 -8 MakeKey 1 0 n -9 MemStore 0 0 -10 MoveTo 1 19 -11 MemLoad 0 0 -12 IdxGT 1 19 -13 IdxRecno 1 0 -14 MoveTo 0 0 -15 Column 0 0 -16 Column 0 1 -17 Callback 2 0 -18 Next 1 11 -19 Close 0 0 -20 Close 1 0 -21 Halt 0 0 -} - -puts { -

    The SELECT begins in a familiar fashion. First the column -names are initialized and the table being queried is opened. -Things become different beginning with instructions 5 and 6 where -the index file is also opened. Instructions 7 and 8 make -a key with the value of 50. -The MemStore instruction at 9 stores -the index key in VDBE memory location 0. The VDBE memory is used to -avoid having to fetch a value from deep in the stack, which can be done, -but makes the program harder to generate. The following instruction -MoveTo at address 10 pops the key off -the stack and moves the index cursor to the first row of the index with -that key. This initializes the cursor for use in the following loop.

    - -

    Instructions 11 through 18 implement a loop over all index records -with the key that was fetched by instruction 8. All of the index -records with this key will be contiguous in the index table, so we walk -through them and fetch the corresponding table key from the index. -This table key is then used to move the cursor to that row in the table. -The rest of the loop is the same as the loop for the non-indexed SELECT -query.

    - -

    The loop begins with the MemLoad -instruction at 11 which pushes a copy of the index key back onto the -stack. The instruction IdxGT at 12 -compares the key to the key in the current index record pointed to by -cursor P1. If the index key at the current cursor location is greater -than the the index we are looking for, then jump out of the loop.

    - -

    The instruction IdxRecno at 13 -pushes onto the stack the table record number from the index. The -following MoveTo pops it and moves the table cursor to that row. The -next 3 instructions select the column data the same way as in the non- -indexed case. The Column instructions fetch the column data and the -callback function is invoked. The final Next instruction advances the -index cursor, not the table cursor, to the next row, and then branches -back to the start of the loop if there are any index records left.

    - -

    Since the index is used to look up values in the table, -it is important that the index and table be kept consistent. -Now that there is an index on the examp table, we will have -to update that index whenever data is inserted, deleted, or -changed in the examp table. Remember the first example above -where we were able to insert a new row into the "examp" table using -12 VDBE instructions. Now that this table is indexed, 19 -instructions are required. The SQL statement is this:

    - -
    -INSERT INTO examp VALUES('Hello, World!',99);
    -
    - -

    And the generated code looks like this:

    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 Transaction 1 0 -1 Transaction 0 0 -2 VerifyCookie 0 256 -3 Integer 0 0 -4 OpenWrite 0 3 examp -5 Integer 0 0 -6 OpenWrite 1 4 examp_idx1 -7 NewRecno 0 0 -8 String 0 0 Hello, World! -9 Integer 99 0 99 -10 Dup 2 1 -11 Dup 1 1 -12 MakeIdxKey 1 0 n -13 IdxPut 1 0 -14 MakeRecord 2 0 -15 PutIntKey 0 1 -16 Close 0 0 -17 Close 1 0 -18 Commit 0 0 -19 Halt 0 0 -} - -puts { -

    At this point, you should understand the VDBE well enough to -figure out on your own how the above program works. So we will -not discuss it further in this text.

    - -

    Joins

    - -

    In a join, two or more tables are combined to generate a single -result. The result table consists of every possible combination -of rows from the tables being joined. The easiest and most natural -way to implement this is with nested loops.

    - -

    Recall the query template discussed above where there was a -single loop that searched through every record of the table. -In a join we have basically the same thing except that there -are nested loops. For example, to join two tables, the query -template might look something like this:

    - -

    -

      -
    1. Initialize the azColumnName[] array for the callback.
    2. -
    3. Open two cursors, one to each of the two tables being queried.
    4. -
    5. For each record in the first table, do: -
        -
      1. For each record in the second table do: -
          -
        1. If the WHERE clause evaluates to FALSE, then skip the steps that - follow and continue to the next record.
        2. -
        3. Compute all columns for the current row of the result.
        4. -
        5. Invoke the callback function for the current row of the result.
        6. -
      2. -
      -
    6. Close both cursors.
    7. -
    -

    - -

    This template will work, but it is likely to be slow since we -are now dealing with an O(N2) loop. But it often works -out that the WHERE clause can be factored into terms and that one or -more of those terms will involve only columns in the first table. -When this happens, we can factor part of the WHERE clause test out of -the inner loop and gain a lot of efficiency. So a better template -would be something like this:

    - -

    -

      -
    1. Initialize the azColumnName[] array for the callback.
    2. -
    3. Open two cursors, one to each of the two tables being queried.
    4. -
    5. For each record in the first table, do: -
        -
      1. Evaluate terms of the WHERE clause that only involve columns from - the first table. If any term is false (meaning that the whole - WHERE clause must be false) then skip the rest of this loop and - continue to the next record.
      2. -
      3. For each record in the second table do: -
          -
        1. If the WHERE clause evaluates to FALSE, then skip the steps that - follow and continue to the next record.
        2. -
        3. Compute all columns for the current row of the result.
        4. -
        5. Invoke the callback function for the current row of the result.
        6. -
      4. -
      -
    6. Close both cursors.
    7. -
    -

    - -

    Additional speed-up can occur if an index can be used to speed -the search of either or the two loops.

    - -

    SQLite always constructs the loops in the same order as the -tables appear in the FROM clause of the SELECT statement. The -left-most table becomes the outer loop and the right-most table -becomes the inner loop. It is possible, in theory, to reorder -the loops in some circumstances to speed the evaluation of the -join. But SQLite does not attempt this optimization.

    - -

    You can see how SQLite constructs nested loops in the following -example:

    - -
    -CREATE TABLE examp2(three int, four int);
    -SELECT * FROM examp, examp2 WHERE two<50 AND four==two;
    -
    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 ColumnName 0 0 examp.one -1 ColumnName 1 0 examp.two -2 ColumnName 2 0 examp2.three -3 ColumnName 3 0 examp2.four -4 Integer 0 0 -5 OpenRead 0 3 examp -6 VerifyCookie 0 909 -7 Integer 0 0 -8 OpenRead 1 5 examp2 -9 Rewind 0 24 -10 Column 0 1 -11 Integer 50 0 50 -12 Ge 1 23 -13 Rewind 1 23 -14 Column 1 1 -15 Column 0 1 -16 Ne 1 22 -17 Column 0 0 -18 Column 0 1 -19 Column 1 0 -20 Column 1 1 -21 Callback 4 0 -22 Next 1 14 -23 Next 0 10 -24 Close 0 0 -25 Close 1 0 -26 Halt 0 0 -} - -puts { -

    The outer loop over table examp is implement by instructions -7 through 23. The inner loop is instructions 13 through 22. -Notice that the "two<50" term of the WHERE expression involves -only columns from the first table and can be factored out of -the inner loop. SQLite does this and implements the "two<50" -test in instructions 10 through 12. The "four==two" test is -implement by instructions 14 through 16 in the inner loop.

    - -

    SQLite does not impose any arbitrary limits on the tables in -a join. It also allows a table to be joined with itself.

    - -

    The ORDER BY clause

    - -

    For historical reasons, and for efficiency, all sorting is currently -done in memory.

    - -

    SQLite implements the ORDER BY clause using a special -set of instructions to control an object called a sorter. In the -inner-most loop of the query, where there would normally be -a Callback instruction, instead a record is constructed that -contains both callback parameters and a key. This record -is added to the sorter (in a linked list). After the query loop -finishes, the list of records is sorted and this list is walked. For -each record on the list, the callback is invoked. Finally, the sorter -is closed and memory is deallocated.

    - -

    We can see the process in action in the following query:

    - -
    -SELECT * FROM examp ORDER BY one DESC, two;
    -
    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 ColumnName 0 0 one -1 ColumnName 1 0 two -2 Integer 0 0 -3 OpenRead 0 3 examp -4 VerifyCookie 0 909 -5 Rewind 0 14 -6 Column 0 0 -7 Column 0 1 -8 SortMakeRec 2 0 -9 Column 0 0 -10 Column 0 1 -11 SortMakeKey 2 0 D+ -12 SortPut 0 0 -13 Next 0 6 -14 Close 0 0 -15 Sort 0 0 -16 SortNext 0 19 -17 SortCallback 2 0 -18 Goto 0 16 -19 SortReset 0 0 -20 Halt 0 0 -} - -puts { -

    There is only one sorter object, so there are no instructions to open -or close it. It is opened automatically when needed, and it is closed -when the VDBE program halts.

    - -

    The query loop is built from instructions 5 through 13. Instructions -6 through 8 build a record that contains the azData[] values for a single -invocation of the callback. A sort key is generated by instructions -9 through 11. Instruction 12 combines the invocation record and the -sort key into a single entry and puts that entry on the sort list.

    - -

    The P3 argument of instruction 11 is of particular interest. The -sort key is formed by prepending one character from P3 to each string -and concatenating all the strings. The sort comparison function will -look at this character to determine whether the sort order is -ascending or descending, and whether to sort as a string or number. -In this example, the first column should be sorted as a string -in descending order so its prefix is "D" and the second column should -sorted numerically in ascending order so its prefix is "+". Ascending -string sorting uses "A", and descending numeric sorting uses "-".

    - -

    After the query loop ends, the table being queried is closed at -instruction 14. This is done early in order to allow other processes -or threads to access that table, if desired. The list of records -that was built up inside the query loop is sorted by the instruction -at 15. Instructions 16 through 18 walk through the record list -(which is now in sorted order) and invoke the callback once for -each record. Finally, the sorter is closed at instruction 19.

    - -

    Aggregate Functions And The GROUP BY and HAVING Clauses

    - -

    To compute aggregate functions, the VDBE implements a special -data structure and instructions for controlling that data structure. -The data structure is an unordered set of buckets, where each bucket -has a key and one or more memory locations. Within the query -loop, the GROUP BY clause is used to construct a key and the bucket -with that key is brought into focus. A new bucket is created with -the key if one did not previously exist. Once the bucket is in -focus, the memory locations of the bucket are used to accumulate -the values of the various aggregate functions. After the query -loop terminates, each bucket is visited once to generate a -single row of the results.

    - -

    An example will help to clarify this concept. Consider the -following query:

    - -
    -SELECT three, min(three+four)+avg(four) 
    -FROM examp2
    -GROUP BY three;
    -
    - - -

    The VDBE code generated for this query is as follows:

    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 ColumnName 0 0 three -1 ColumnName 1 0 min(three+four)+avg(four) -2 AggReset 0 3 -3 AggInit 0 1 ptr(0x7903a0) -4 AggInit 0 2 ptr(0x790700) -5 Integer 0 0 -6 OpenRead 0 5 examp2 -7 VerifyCookie 0 909 -8 Rewind 0 23 -9 Column 0 0 -10 MakeKey 1 0 n -11 AggFocus 0 14 -12 Column 0 0 -13 AggSet 0 0 -14 Column 0 0 -15 Column 0 1 -16 Add 0 0 -17 Integer 1 0 -18 AggFunc 0 1 ptr(0x7903a0) -19 Column 0 1 -20 Integer 2 0 -21 AggFunc 0 1 ptr(0x790700) -22 Next 0 9 -23 Close 0 0 -24 AggNext 0 31 -25 AggGet 0 0 -26 AggGet 0 1 -27 AggGet 0 2 -28 Add 0 0 -29 Callback 2 0 -30 Goto 0 24 -31 Noop 0 0 -32 Halt 0 0 -} - -puts { -

    The first instruction of interest is the -AggReset at 2. -The AggReset instruction initializes the set of buckets to be the -empty set and specifies the number of memory slots available in each -bucket as P2. In this example, each bucket will hold 3 memory slots. -It is not obvious, but if you look closely at the rest of the program -you can figure out what each of these slots is intended for.

    - -
    - - - - -
    Memory SlotIntended Use Of This Memory Slot
    0The "three" column -- the key to the bucket
    1The minimum "three+four" value
    2The sum of all "four" values. This is used to compute - "avg(four)".
    - -

    The query loop is implemented by instructions 8 through 22. -The aggregate key specified by the GROUP BY clause is computed -by instructions 9 and 10. Instruction 11 causes the appropriate -bucket to come into focus. If a bucket with the given key does -not already exists, a new bucket is created and control falls -through to instructions 12 and 13 which initialize the bucket. -If the bucket does already exist, then a jump is made to instruction -14. The values of aggregate functions are updated by the instructions -between 11 and 21. Instructions 14 through 18 update memory -slot 1 to hold the next value "min(three+four)". Then the sum of the -"four" column is updated by instructions 19 through 21.

    - -

    After the query loop is finished, the table "examp2" is closed at -instruction 23 so that its lock will be released and it can be -used by other threads or processes. The next step is to loop -over all aggregate buckets and output one row of the result for -each bucket. This is done by the loop at instructions 24 -through 30. The AggNext instruction at 24 brings the next bucket -into focus, or jumps to the end of the loop if all buckets have -been examined already. The 3 columns of the result are fetched from -the aggregator bucket in order at instructions 25 through 27. -Finally, the callback is invoked at instruction 29.

    - -

    In summary then, any query with aggregate functions is implemented -by two loops. The first loop scans the input table and computes -aggregate information into buckets and the second loop scans through -all the buckets to compute the final result.

    - -

    The realization that an aggregate query is really two consequtive -loops makes it much easier to understand the difference between -a WHERE clause and a HAVING clause in SQL query statement. The -WHERE clause is a restriction on the first loop and the HAVING -clause is a restriction on the second loop. You can see this -by adding both a WHERE and a HAVING clause to our example query:

    - - -
    -SELECT three, min(three+four)+avg(four) 
    -FROM examp2
    -WHERE three>four
    -GROUP BY three
    -HAVING avg(four)<10;
    -
    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 ColumnName 0 0 three -1 ColumnName 1 0 min(three+four)+avg(four) -2 AggReset 0 3 -3 AggInit 0 1 ptr(0x7903a0) -4 AggInit 0 2 ptr(0x790700) -5 Integer 0 0 -6 OpenRead 0 5 examp2 -7 VerifyCookie 0 909 -8 Rewind 0 26 -9 Column 0 0 -10 Column 0 1 -11 Le 1 25 -12 Column 0 0 -13 MakeKey 1 0 n -14 AggFocus 0 17 -15 Column 0 0 -16 AggSet 0 0 -17 Column 0 0 -18 Column 0 1 -19 Add 0 0 -20 Integer 1 0 -21 AggFunc 0 1 ptr(0x7903a0) -22 Column 0 1 -23 Integer 2 0 -24 AggFunc 0 1 ptr(0x790700) -25 Next 0 9 -26 Close 0 0 -27 AggNext 0 37 -28 AggGet 0 2 -29 Integer 10 0 10 -30 Ge 1 27 -31 AggGet 0 0 -32 AggGet 0 1 -33 AggGet 0 2 -34 Add 0 0 -35 Callback 2 0 -36 Goto 0 27 -37 Noop 0 0 -38 Halt 0 0 -} - -puts { -

    The code generated in this last example is the same as the -previous except for the addition of two conditional jumps used -to implement the extra WHERE and HAVING clauses. The WHERE -clause is implemented by instructions 9 through 11 in the query -loop. The HAVING clause is implemented by instruction 28 through -30 in the output loop.

    - -

    Using SELECT Statements As Terms In An Expression

    - -

    The very name "Structured Query Language" tells us that SQL should -support nested queries. And, in fact, two different kinds of nesting -are supported. Any SELECT statement that returns a single-row, single-column -result can be used as a term in an expression of another SELECT statement. -And, a SELECT statement that returns a single-column, multi-row result -can be used as the right-hand operand of the IN and NOT IN operators. -We will begin this section with an example of the first kind of nesting, -where a single-row, single-column SELECT is used as a term in an expression -of another SELECT. Here is our example:

    - -
    -SELECT * FROM examp
    -WHERE two!=(SELECT three FROM examp2
    -            WHERE four=5);
    -
    - -

    The way SQLite deals with this is to first run the inner SELECT -(the one against examp2) and store its result in a private memory -cell. SQLite then substitutes the value of this private memory -cell for the inner SELECT when it evaluates the outer SELECT. -The code looks like this:

    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 String 0 0 -1 MemStore 0 1 -2 Integer 0 0 -3 OpenRead 1 5 examp2 -4 VerifyCookie 0 909 -5 Rewind 1 13 -6 Column 1 1 -7 Integer 5 0 5 -8 Ne 1 12 -9 Column 1 0 -10 MemStore 0 1 -11 Goto 0 13 -12 Next 1 6 -13 Close 1 0 -14 ColumnName 0 0 one -15 ColumnName 1 0 two -16 Integer 0 0 -17 OpenRead 0 3 examp -18 Rewind 0 26 -19 Column 0 1 -20 MemLoad 0 0 -21 Eq 1 25 -22 Column 0 0 -23 Column 0 1 -24 Callback 2 0 -25 Next 0 19 -26 Close 0 0 -27 Halt 0 0 -} - -puts { -

    The private memory cell is initialized to NULL by the first -two instructions. Instructions 2 through 13 implement the inner -SELECT statement against the examp2 table. Notice that instead of -sending the result to a callback or storing the result on a sorter, -the result of the query is pushed into the memory cell by instruction -10 and the loop is abandoned by the jump at instruction 11. -The jump at instruction at 11 is vestigial and never executes.

    - -

    The outer SELECT is implemented by instructions 14 through 25. -In particular, the WHERE clause that contains the nested select -is implemented by instructions 19 through 21. You can see that -the result of the inner select is loaded onto the stack by instruction -20 and used by the conditional jump at 21.

    - -

    When the result of a sub-select is a scalar, a single private memory -cell can be used, as shown in the previous -example. But when the result of a sub-select is a vector, such -as when the sub-select is the right-hand operand of IN or NOT IN, -a different approach is needed. In this case, -the result of the sub-select is -stored in a transient table and the contents of that table -are tested using the Found or NotFound operators. Consider this -example:

    - -
    -SELECT * FROM examp
    -WHERE two IN (SELECT three FROM examp2);
    -
    - -

    The code generated to implement this last query is as follows:

    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 OpenTemp 1 1 -1 Integer 0 0 -2 OpenRead 2 5 examp2 -3 VerifyCookie 0 909 -4 Rewind 2 10 -5 Column 2 0 -6 IsNull -1 9 -7 String 0 0 -8 PutStrKey 1 0 -9 Next 2 5 -10 Close 2 0 -11 ColumnName 0 0 one -12 ColumnName 1 0 two -13 Integer 0 0 -14 OpenRead 0 3 examp -15 Rewind 0 25 -16 Column 0 1 -17 NotNull -1 20 -18 Pop 1 0 -19 Goto 0 24 -20 NotFound 1 24 -21 Column 0 0 -22 Column 0 1 -23 Callback 2 0 -24 Next 0 16 -25 Close 0 0 -26 Halt 0 0 -} - -puts { -

    The transient table in which the results of the inner SELECT are -stored is created by the OpenTemp -instruction at 0. This opcode is used for tables that exist for the -duration of a single SQL statement only. 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 P2 value -of 1 means the cursor points to a BTree index, which has no data but can -have an arbitrary key.

    - -

    The inner SELECT statement is implemented by instructions 1 through 10. -All this code does is make an entry in the temporary table for each -row of the examp2 table with a non-NULL value for the "three" column. -The key for each temporary table entry is the "three" column of examp2 -and the data is an empty string since it is never used.

    - -

    The outer SELECT is implemented by instructions 11 through 25. In -particular, the WHERE clause containing the IN operator is implemented -by instructions at 16, 17, and 20. Instruction 16 pushes the value of -the "two" column for the current row onto the stack and instruction 17 -checks to see that it is non-NULL. If this is successful, execution -jumps to 20, where it tests to see if top of the stack matches any key -in the temporary table. The rest of the code is the same as what has -been shown before.

    - -

    Compound SELECT Statements

    - -

    SQLite also allows two or more SELECT statements to be joined as -peers using operators UNION, UNION ALL, INTERSECT, and EXCEPT. These -compound select statements are implemented using transient tables. -The implementation is slightly different for each operator, but the -basic ideas are the same. For an example we will use the EXCEPT -operator.

    - -
    -SELECT two FROM examp
    -EXCEPT
    -SELECT four FROM examp2;
    -
    - -

    The result of this last example should be every unique value -of the "two" column in the examp table, except any value that is -in the "four" column of examp2 is removed. The code to implement -this query is as follows:

    -} - -Code { -addr opcode p1 p2 p3 ----- ------------ ----- ----- ----------------------------------- -0 OpenTemp 0 1 -1 KeyAsData 0 1 -2 Integer 0 0 -3 OpenRead 1 3 examp -4 VerifyCookie 0 909 -5 Rewind 1 11 -6 Column 1 1 -7 MakeRecord 1 0 -8 String 0 0 -9 PutStrKey 0 0 -10 Next 1 6 -11 Close 1 0 -12 Integer 0 0 -13 OpenRead 2 5 examp2 -14 Rewind 2 20 -15 Column 2 1 -16 MakeRecord 1 0 -17 NotFound 0 19 -18 Delete 0 0 -19 Next 2 15 -20 Close 2 0 -21 ColumnName 0 0 four -22 Rewind 0 26 -23 Column 0 0 -24 Callback 1 0 -25 Next 0 23 -26 Close 0 0 -27 Halt 0 0 -} - -puts { -

    The transient table in which the result is built is created by -instruction 0. Three loops then follow. The loop at instructions -5 through 10 implements the first SELECT statement. The second -SELECT statement is implemented by the loop at instructions 14 through -19. Finally, a loop at instructions 22 through 25 reads the transient -table and invokes the callback once for each row in the result.

    - -

    Instruction 1 is of particular importance in this example. Normally, -the Column instruction extracts the value of a column from a larger -record in the data of an SQLite file entry. Instruction 1 sets a flag on -the transient table so that Column will instead treat the key of the -SQLite file entry as if it were data and extract column information from -the key.

    - -

    Here is what is going to happen: The first SELECT statement -will construct rows of the result and save each row as the key of -an entry in the transient table. The data for each entry in the -transient table is a never used so we fill it in with an empty string. -The second SELECT statement also constructs rows, but the rows -constructed by the second SELECT are removed from the transient table. -That is why we want the rows to be stored in the key of the SQLite file -instead of in the data -- so they can be easily located and deleted.

    - -

    Let's look more closely at what is happening here. The first -SELECT is implemented by the loop at instructions 5 through 10. -Instruction 5 intializes the loop by rewinding its cursor. -Instruction 6 extracts the value of the "two" column from "examp" -and instruction 7 converts this into a row. Instruction 8 pushes -an empty string onto the stack. Finally, instruction 9 writes the -row into the temporary table. But remember, the PutStrKey opcode uses -the top of the stack as the record data and the next on stack as the -key. For an INSERT statement, the row generated by the -MakeRecord opcode is the record data and the record key is an integer -created by the NewRecno opcode. But here the roles are reversed and -the row created by MakeRecord is the record key and the record data is -just an empty string.

    - -

    The second SELECT is implemented by instructions 14 through 19. -Instruction 14 intializes the loop by rewinding its cursor. -A new result row is created from the "four" column of table "examp2" -by instructions 15 and 16. But instead of using PutStrKey to write this -new row into the temporary table, we instead call Delete to remove -it from the temporary table if it exists.

    - -

    The result of the compound select is sent to the callback routine -by the loop at instructions 22 through 25. There is nothing new -or remarkable about this loop, except for the fact that the Column -instruction at 23 will be extracting a column out of the record key -rather than the record data.

    - -

    Summary

    - -

    This article has reviewed all of the major techniques used by -SQLite's VDBE to implement SQL statements. What has not been shown -is that most of these techniques can be used in combination to -generate code for an appropriately complex query statement. For -example, we have shown how sorting is accomplished on a simple query -and we have shown how to implement a compound query. But we did -not give an example of sorting in a compound query. This is because -sorting a compound query does not introduce any new concepts: it -merely combines two previous ideas (sorting and compounding) -in the same VDBE program.

    - -

    For additional information on how the SQLite library -functions, the reader is directed to look at the SQLite source -code directly. If you understand the material in this article, -you should not have much difficulty in following the sources. -Serious students of the internals of SQLite will probably -also what to make a careful study of the VDBE opcodes -as documented here. Most of the -opcode documentation is extracted from comments in the source -code using a script so you can also get information about the -various opcodes directly from the vdbe.c source file. -If you have successfully read this far, you should have little -difficulty understanding the rest.

    - -

    If you find errors in either the documentation or the code, -feel free to fix them and/or contact the author at -drh@hwaci.com. Your bug fixes or -suggestions are always welcomed.

    -} -footer $rcsid diff --git a/sqlite/www/whentouse.tcl b/sqlite/www/whentouse.tcl deleted file mode 100644 index 9893f96..0000000 --- a/sqlite/www/whentouse.tcl +++ /dev/null @@ -1,252 +0,0 @@ -# -# Run this TCL script to generate HTML for the goals.html file. -# -set rcsid {$Id: whentouse.tcl,v 1.4 2005/01/20 22:48:49 drh Exp $} -source common.tcl -header {Appropriate Uses For SQLite} - -puts { -

    -SQLite is different from most other SQL database engines in that its -primary design goal is to be simple: -

    - -
      -
    • Simple to administer
    • -
    • Simple to operate
    • -
    • Simple to embed in a larger program
    • -
    • Simple to maintain and customize
    • -
    - -

    -Many people like SQLite because it is small and fast. But those -qualities are just happy accidents. -Users also find that SQLite is very reliable. Reliability is -a consequence of simplicity. With less complication, there is -less to go wrong. So, yes, SQLite is small, fast, and reliable, -but first and foremost, SQLite strives to be simple. -

    - -

    -Simplicity in a database engine can be either a strength or a -weakness, depending on what you are trying to do. In order to -achieve simplicity, SQLite has had to sacrifice other characteristics -that some people find useful, such as high concurrency, fine-grained -access control, a rich set of built-in functions, stored procedures, -esoteric SQL language features, XML and/or Java extensions, -tera- or peta-byte scalability, and so forth. If you need some of these -latter of features and do not mind the added complexity that they -bring, then SQLite is probably not the database for you. -SQLite is not intended to be an enterprise database engine. It -not designed to compete with Oracle or PostgreSQL. -

    - -

    -The basic rule of thumb for when it is appropriate to use SQLite is -this: Use SQLite in situations where simplicity of administration, -implementation, and maintenance are more important than the countless -complex features that enterprise database engines provide. -As it turns out, situations where simplicity is the better choice -are more common that many people realize. -

    - -

    Situations Where SQLite Works Well

    - -
      -
    • Websites

      - -

      SQLite usually will work great as the database engine for low to -medium traffic websites (which is to say, 99.9% of all websites). -The amount of web traffic that SQLite can handle depends, of course, -on how heavily the website uses its database. Generally -speaking, any site that gets fewer than a 100000 hits/day should work -fine with SQLite. -The 100000 hits/day figure is a conservative estimate, not a -hard upper bound. -SQLite has been demonstrated to work with 10 times that amount -of traffic.

      -
    • - -
    • Embedded devices and applications

      - -

      Because an SQLite database requires little or no administration, -SQLite is a good choice for devices or services that must work -unattended and without human support. SQLite is a good fit for -use in cellphones, PDAs, set-top boxes, and/or appliances. It also -works well as an embedded database in downloadable consumer applications. -

      -
    • - -
    • Application File Format

      - -

      -SQLite has been used with great success as the on-disk file format -for desktop applications such as financial analysis tools, CAD -packages, record keeping programs, and so forth. The traditional -File/Open operation does an sqlite3_open() and executes a -BEGIN TRANSACTION to get exclusive access to the content. File/Save -does a COMMIT followed by another BEGIN TRANSACTION. The use -of transactions guarantees that updates to the application file are atomic, -durable, isolated, and consistent. -

      - -

      -Temporary triggers can be added to the database to record all -changes into a (temporary) undo/redo log table. These changes can then -be played back when the user presses the Undo and Redo buttons. Using -this technique, a unlimited depth undo/redo implementation can be written -in surprising little code. -

      -
    • - -
    • Replacement for ad hoc disk files

      - -

      Many programs use fopen(), fread(), and fwrite() to create and -manage files of data in home-grown formats. SQLite works -particularly well as a -replacement for these ad hoc data files.

      -
    • - -
    • Internal or temporary databases

      - -

      -For programs that have a lot of data that must be sifted and sorted -in diverse ways, it is often easier and quicker to load the data into -an in-memory SQLite database and use queries with joins and ORDER BY -clauses to extract the data in the form and order needed rather than -to try to code the same operations manually. -Using an SQL database internally in this way also gives the program -greater flexibility since new columns and indices can be added without -having to recode every query. -

      -
    • - -
    • Command-line dataset analysis tool

      - -

      -Experienced SQL users can employ -the command-line sqlite program to analyze miscellaneous -datasets. Raw data can be imported from CSV files, then that -data can be sliced and diced to generate a myriad of summary -reports. Possible uses include website log analysis, sports -statistics analysis, compilation of programming metrics, and -analysis of experimental results. -

      - -

      -You can also do the same thing with a enterprise client/server -database, of course. The advantages to using SQLite in this situation -are that SQLite is much easier to set up and the resulting database -is a single file that you can store on a floppy disk or flash-memory stick -or email to a colleague. -

      -
    • - -
    • Stand-in for an enterprise database during demos or testing

      - -

      -If you are writing a client application for an enterprise database engine, -it makes sense to use a generic database backend that allows you to connect -to many different kinds of SQL database engines. It makes even better -sense to -go ahead and include SQLite in the mix of supported database and to statically -link the SQLite engine in with the client. That way the client program -can be used standalone with an SQLite data file for testing or for -demonstrations. -

      -
    • - -
    • Database Pedagogy

      - -

      -Because it is simple to setup and use (installation is trivial: just -copy the sqlite or sqlite.exe executable to the target machine -and run it) SQLite makes a good database engine for use in teaching SQL. -Students can easily create as many databases as they like and can -email databases to the instructor for comments or grading. For more -advanced students who are interested in studying how an RDBMS is -implemented, the modular and well-commented and documented SQLite code -can serve as a good basis. This is not to say that SQLite is an accurate -model of how other database engines are implemented, but rather a student who -understands how SQLite works can more quickly comprehend the operational -principles of other systems. -

      -
    • - -
    • Experimental SQL language extensions

      - -

      The simple, modular design of SQLite makes it a good platform for -prototyping new, experimental database language features or ideas. -

      -
    • - - -
    - -

    Situations Where Another RDBMS May Work Better

    - -
      -
    • Client/Server Applications

      - -

      If you have many client programs accessing a common database -over a network, you should consider using a client/server database -engine instead of SQLite. SQLite will work over a network filesystem, -but because of the latency associated with most network filesystems, -performance will not be great. Also, the file locking logic of -many network filesystems implementation contains bugs (on both Unix -and windows). If file locking does not work like it should, -it might be possible for two or more client programs to modify the -same part of the same database at the same time, resulting in -database corruption. Because this problem results from bugs in -the underlying filesystem implementation, there is nothing SQLite -can do to prevent it.

      - -

      A good rule of thumb is that you should avoid using SQLite -in situations where the same database will be accessed simultaneously -from many computers over a network filesystem.

      -
    • - -
    • High-volume Websites

      - -

      SQLite will normally work fine as the database backend to a website. -But if you website is so busy that your are thinking of splitting the -database component off onto a separate machine, then you should -definitely consider using an enterprise-class client/server database -engine instead of SQLite.

      -
    • - -
    • Very large datasets

      - -

      When you start a transaction in SQLite (which happens automatically -before any write operation that is not within an explicit BEGIN...COMMIT) -the engine has to allocate a bitmap of dirty pages in the disk file to -help it manage its rollback journal. SQLite needs 256 bytes of RAM for -every 1MB of database. For smaller databases, the amount of memory -required is not a problem, but when database begin to grow into the -multi-gigabyte range, the size of the bitmap can get quite large. If -you need to store and modify more than a few dozen GB of data, you should -consider using a different database engine. -

      -
    • - -
    • High Concurrency

      - -

      -SQLite uses reader/writer locks on the entire database file. That means -if any process is reading from any part of the database, all other -processes are prevented from writing any other part of the database. -Similarly, if any one process is writing to the database, -all other processes are prevented from reading any other part of the -database. -For many situations, this is not a problem. Each application -does its database work quickly and moves on, and no lock lasts for more -than a few dozen milliseconds. But there are some applications that require -more concurrency, and those applications may need to seek a different -solution. -

      -
    • - -
    - -} -footer $rcsid -- 2.7.4