1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-24 22:22:08 +03:00

Merge trunk changes into sessions branch.

FossilOrigin-Name: b91b4c31fe311b292044c9c747feba294ffce25c
This commit is contained in:
dan
2011-04-18 17:30:56 +00:00
22 changed files with 1560 additions and 518 deletions

View File

@ -1 +1 @@
3.7.6 3.7.6.1

18
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.7.6. # Generated by GNU Autoconf 2.62 for sqlite 3.7.6.1.
# #
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='sqlite' PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite' PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.7.6' PACKAGE_VERSION='3.7.6.1'
PACKAGE_STRING='sqlite 3.7.6' PACKAGE_STRING='sqlite 3.7.6.1'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
# Factoring default headers for most tests. # Factoring default headers for most tests.
@ -1485,7 +1485,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # 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. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures sqlite 3.7.6 to adapt to many kinds of systems. \`configure' configures sqlite 3.7.6.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1550,7 +1550,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.7.6:";; short | recursive ) echo "Configuration of sqlite 3.7.6.1:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1666,7 +1666,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
sqlite configure 3.7.6 sqlite configure 3.7.6.1
generated by GNU Autoconf 2.62 generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@ -1680,7 +1680,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.7.6, which was It was created by sqlite $as_me 3.7.6.1, which was
generated by GNU Autoconf 2.62. Invocation command line was generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@ $ $0 $@
@ -13942,7 +13942,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by sqlite $as_me 3.7.6, which was This file was extended by sqlite $as_me 3.7.6.1, which was
generated by GNU Autoconf 2.62. Invocation command line was generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -13995,7 +13995,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\ ac_cs_version="\\
sqlite config.status 3.7.6 sqlite config.status 3.7.6.1
configured by $0, generated by GNU Autoconf 2.62, configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View File

@ -1,11 +1,11 @@
C Fix\sfurther\smissing\scomments\sand\sother\sminor\sissues\sin\sthe\ssession\smodule\scode. C Merge\strunk\schanges\sinto\ssessions\sbranch.
D 2011-04-18T15:47:08.694 D 2011-04-18T17:30:56.521
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.vxworks c85ec1d8597fe2f7bc225af12ac1666e21379151 F Makefile.vxworks c85ec1d8597fe2f7bc225af12ac1666e21379151
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION d1056b26608c9a2695187d57cac12ae89492639d F VERSION c97e5dcdea2407f4a94f9740294cdf39ce9e88c4
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531 F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248 F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248
@ -22,7 +22,7 @@ F art/src_logo.gif 9341ef09f0e53cd44c0c9b6fc3c16f7f3d6c2ad9
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 868fdb48c028421a203470e15c69ada15b9ba673 F config.h.in 868fdb48c028421a203470e15c69ada15b9ba673
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure c38c1947db7ed4adaed2affcb09cea9d3acd5a9a x F configure 61dbf78cdc4d6a871333dc599c130be6cce865c5 x
F configure.ac 87a3c71bbe9c925381c154413eea7f3cdc397244 F configure.ac 87a3c71bbe9c925381c154413eea7f3cdc397244
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538 F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
@ -154,7 +154,7 @@ F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85 F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85
F src/main.c 8b97db74cb876bf34ca4fb3720b18e4ffdcf9fd5 F src/main.c 8b97db74cb876bf34ca4fb3720b18e4ffdcf9fd5
F src/malloc.c 788f2ed928786dfe305b6783d551d6b1a9080976 F src/malloc.c 74c740e8ba22b806cfb980c8c0ddea1cbd54a20e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf
@ -164,16 +164,16 @@ F src/memjournal.c 0ebce851677a7ac035ba1512a7e65851b34530c6
F src/mutex.c 6949180803ff05a7d0e2b9334a95b4fb5a00e23f F src/mutex.c 6949180803ff05a7d0e2b9334a95b4fb5a00e23f
F src/mutex.h fe2ef5e1c4dae531d5a544f9241f19c56d26803d F src/mutex.h fe2ef5e1c4dae531d5a544f9241f19c56d26803d
F src/mutex_noop.c d5cfbca87168c661a0b118cd8e329a908e453151 F src/mutex_noop.c d5cfbca87168c661a0b118cd8e329a908e453151
F src/mutex_os2.c f5d09e85b914643c230aa97db709fc0db370d93c F src/mutex_os2.c 882d735098c07c8c6a5472b8dd66e19675fe117f
F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579 F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579
F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33 F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 2596fd2d5d0976c6c0c628d0c3c7c4e7a724f4cf F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
F src/os_unix.c a8fe62148d41e54e383d3360a711a01595feef58 F src/os_unix.c d7889a0f9389c8c2e1d3b380f5aa1256c22a90e8
F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845 F src/os_win.c d149b9a7dfdd38de09afc054f8168cd3cd80630b
F src/pager.c 055239dcdfe12b3f5d97f6f01f85da01e2d6d912 F src/pager.c 055239dcdfe12b3f5d97f6f01f85da01e2d6d912
F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
@ -186,9 +186,9 @@ F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c 649a6f10f7eb7b52a5a28847773cb9968a828ae8 F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff
F src/shell.c 9c8389796764f65d4506bcd614ac8061f4160d5c F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79
F src/sqlite.h.in 9cff46ef60540f044c1b665db606aa63ba67048f F src/sqlite.h.in 0cf61c41c48e1e6b863ff8cf9ecd69620932330e
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
F src/sqliteInt.h 9a29e5bb82f3abef6b4af91e18d637050fa3c883 F src/sqliteInt.h 9a29e5bb82f3abef6b4af91e18d637050fa3c883
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
@ -243,7 +243,7 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080
F src/trigger.c 144cc18bb701f3286484aae4292a9531f09278c8 F src/trigger.c 144cc18bb701f3286484aae4292a9531f09278c8
F src/update.c 3f3f3bb734a0da1dffd0ed33e504642b35ed3605 F src/update.c 3f3f3bb734a0da1dffd0ed33e504642b35ed3605
F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60 F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60
F src/util.c cd997077bad039efc0597eb027c929658f93c018 F src/util.c 465fe10aabf0ca7d7826a156dab919b0b65c525a
F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e
F src/vdbe.c dd53dda1cf786397e72643a497b5c2f368ff11ba F src/vdbe.c dd53dda1cf786397e72643a497b5c2f368ff11ba
F src/vdbe.h 44fd57aeed86da0cd31206626c13cdde0e72cc0e F src/vdbe.h 44fd57aeed86da0cd31206626c13cdde0e72cc0e
@ -398,7 +398,7 @@ F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062 F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062
F test/exclusive2.test 343d55130c12c67b8bf10407acec043a6c26c86b F test/exclusive2.test 343d55130c12c67b8bf10407acec043a6c26c86b
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 81363f6982ea49dfd820a50845466390e60a4a0c F test/exists.test 5e2d64b4eb5a9d08876599bdae2e1213d2d12e2a
F test/expr.test 19e8ac40313e2282a47b586d11c4892040990d3a F test/expr.test 19e8ac40313e2282a47b586d11c4892040990d3a
F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6 F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
@ -623,7 +623,7 @@ F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 F test/quota.test 48c3a5a98687d67ef06fc16d2e603284756bbec3
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a
@ -688,7 +688,7 @@ F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/superlock.test 5d7a4954b0059c903f82c7b67867bc5451a7c082 F test/superlock.test 5d7a4954b0059c903f82c7b67867bc5451a7c082
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3 F test/sync.test 2bd73b585089c99e76b3e1796c42059b7d89d872
F test/syscall.test 707c95e4ab7863e13f1293c6b0c76bead30249b3 F test/syscall.test 707c95e4ab7863e13f1293c6b0c76bead30249b3
F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f
F test/table.test 04ba066432430657712d167ebf28080fe878d305 F test/table.test 04ba066432430657712d167ebf28080fe878d305
@ -838,7 +838,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31 F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31
F test/triggerA.test eaf11a29db2a11967d2d4b49d37f92bce598194e F test/triggerA.test eaf11a29db2a11967d2d4b49d37f92bce598194e
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
F test/triggerC.test 8a691ff6dd47df2e57395bbec4b62101fac0f363 F test/triggerC.test 811ab569af9e6fc894afbcc0d77d14500b2406c5
F test/triggerD.test c6add3817351451e419f6ff9e9a259b02b6e2de7 F test/triggerD.test c6add3817351451e419f6ff9e9a259b02b6e2de7
F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
@ -846,6 +846,7 @@ F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84
F test/types3.test a0f66bf12f80fad89493535474f7a6d16fa58150 F test/types3.test a0f66bf12f80fad89493535474f7a6d16fa58150
F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2 F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2
F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e
F test/unordered.test e81169ce2a8f31b2c6b66af691887e1376ab3ced
F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172 F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
F test/vacuum.test 29b60e8cc9e573b39676df6c4a75fe9e02d04a09 F test/vacuum.test 29b60e8cc9e573b39676df6c4a75fe9e02d04a09
@ -873,7 +874,7 @@ F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
F test/wal.test 5617ad308bfdb8a8885220d8a261a6096a8d7e57 F test/wal.test 5617ad308bfdb8a8885220d8a261a6096a8d7e57
F test/wal2.test e561a8c6fdd1c2cd1876f3e39757934e7b7361f8 F test/wal2.test aa0fb2314b3235be4503c06873e41ebfc0757782
F test/wal3.test 5c396cc22497244d627306f4c1d360167353f8dd F test/wal3.test 5c396cc22497244d627306f4c1d360167353f8dd
F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30 F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
F test/wal5.test 1bbfaa316dc2a1d0d1fac3f4500c38a90055a41b F test/wal5.test 1bbfaa316dc2a1d0d1fac3f4500c38a90055a41b
@ -920,12 +921,13 @@ F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
F tool/omittest.tcl b1dd290c1596e0f31fd335160a74ec5dfea3df4a F tool/omittest.tcl b1dd290c1596e0f31fd335160a74ec5dfea3df4a
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/shell1.test f608a009b04c490fd360c5ded458a6f98b4e7ec4 F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/shell1.test fee04fce1bf55e6e081523545fd4e0e83490ff8e
F tool/shell2.test 5dc76b8005b465f420fed8241621da7513060ff3 F tool/shell2.test 5dc76b8005b465f420fed8241621da7513060ff3
F tool/shell3.test 4fad469e8003938426355afdf34155f08c587836 F tool/shell3.test 4fad469e8003938426355afdf34155f08c587836
F tool/shell4.test 35f9c3d452b4e76d5013c63e1fd07478a62f14ce F tool/shell4.test 35f9c3d452b4e76d5013c63e1fd07478a62f14ce
F tool/shell5.test 62bfaf9267296da1b91e4b1c03e44e7b393f6a94 F tool/shell5.test 62bfaf9267296da1b91e4b1c03e44e7b393f6a94
F tool/showdb.c 471c0f8fa472e71bb7654500096a5bdb4ea1fb2a F tool/showdb.c 43e913d954684c2f5007dcab46d1a1308852a0ad
F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02
F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9 F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
@ -938,7 +940,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 20d7c280235201e519f296372f269e7cecda24da P 99f0f35092b0b78b7016b21c242da263ab64b77b 3e135748f1efacb52b414b3ac3f4ae2c08bcd8fb
R 22fa2c52781f892ef560f2c8f63b1707 R b2692e50ee7820b096983b9aa33c1efd
U dan U dan
Z e6f0d0d675f579cb5b46b0fe2c73f457 Z c7fa020efb14904762c294d2eedf7456

View File

@ -1 +1 @@
99f0f35092b0b78b7016b21c242da263ab64b77b b91b4c31fe311b292044c9c747feba294ffce25c

View File

@ -266,7 +266,7 @@ static int mallocWithAlarm(int n, void **pp){
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n); sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmCallback!=0 ){ if( mem0.alarmCallback!=0 ){
int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed+nFull >= mem0.alarmThreshold ){ if( nUsed >= mem0.alarmThreshold - nFull ){
mem0.nearlyFull = 1; mem0.nearlyFull = 1;
sqlite3MallocAlarm(nFull); sqlite3MallocAlarm(nFull);
}else{ }else{
@ -507,7 +507,7 @@ void sqlite3DbFree(sqlite3 *db, void *p){
** Change the size of an existing memory allocation ** Change the size of an existing memory allocation
*/ */
void *sqlite3Realloc(void *pOld, int nBytes){ void *sqlite3Realloc(void *pOld, int nBytes){
int nOld, nNew; int nOld, nNew, nDiff;
void *pNew; void *pNew;
if( pOld==0 ){ if( pOld==0 ){
return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */ return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
@ -530,8 +530,9 @@ void *sqlite3Realloc(void *pOld, int nBytes){
}else if( sqlite3GlobalConfig.bMemstat ){ }else if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex); sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes); sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= nDiff = nNew - nOld;
mem0.alarmThreshold ){ if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
mem0.alarmThreshold-nDiff ){
sqlite3MallocAlarm(nNew-nOld); sqlite3MallocAlarm(nNew-nOld);
} }
assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
@ -543,7 +544,7 @@ void *sqlite3Realloc(void *pOld, int nBytes){
} }
if( pNew ){ if( pNew ){
nNew = sqlite3MallocSize(pNew); nNew = sqlite3MallocSize(pNew);
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nDiff);
} }
sqlite3_mutex_leave(mem0.mutex); sqlite3_mutex_leave(mem0.mutex);
}else{ }else{

View File

@ -251,7 +251,7 @@ static void os2MutexLeave(sqlite3_mutex *p){
#endif #endif
} }
SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
static const sqlite3_mutex_methods sMutex = { static const sqlite3_mutex_methods sMutex = {
os2MutexInit, os2MutexInit,
os2MutexEnd, os2MutexEnd,

File diff suppressed because it is too large Load Diff

View File

@ -293,7 +293,7 @@ static struct unix_syscall {
sqlite3_syscall_ptr pDefault; /* Default value */ sqlite3_syscall_ptr pDefault; /* Default value */
} aSyscall[] = { } aSyscall[] = {
{ "open", (sqlite3_syscall_ptr)open, 0 }, { "open", (sqlite3_syscall_ptr)open, 0 },
#define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) #define osOpen ((int(*)(const char*,int,...))aSyscall[0].pCurrent)
{ "close", (sqlite3_syscall_ptr)close, 0 }, { "close", (sqlite3_syscall_ptr)close, 0 },
#define osClose ((int(*)(int))aSyscall[1].pCurrent) #define osClose ((int(*)(int))aSyscall[1].pCurrent)
@ -330,7 +330,7 @@ static struct unix_syscall {
{ "read", (sqlite3_syscall_ptr)read, 0 }, { "read", (sqlite3_syscall_ptr)read, 0 },
#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) #define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)
#if defined(USE_PREAD) || defined(SQLITE_ENABLE_LOCKING_STYLE) #if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
{ "pread", (sqlite3_syscall_ptr)pread, 0 }, { "pread", (sqlite3_syscall_ptr)pread, 0 },
#else #else
{ "pread", (sqlite3_syscall_ptr)0, 0 }, { "pread", (sqlite3_syscall_ptr)0, 0 },
@ -347,7 +347,7 @@ static struct unix_syscall {
{ "write", (sqlite3_syscall_ptr)write, 0 }, { "write", (sqlite3_syscall_ptr)write, 0 },
#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) #define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
#if defined(USE_PREAD) || defined(SQLITE_ENABLE_LOCKING_STYLE) #if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
{ "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 },
#else #else
{ "pwrite", (sqlite3_syscall_ptr)0, 0 }, { "pwrite", (sqlite3_syscall_ptr)0, 0 },
@ -363,7 +363,11 @@ static struct unix_syscall {
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\ #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
aSyscall[13].pCurrent) aSyscall[13].pCurrent)
#if SQLITE_ENABLE_LOCKING_STYLE
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
#else
{ "fchmod", (sqlite3_syscall_ptr)0, 0 },
#endif
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
@ -929,7 +933,7 @@ struct unixInodeInfo {
UnixUnusedFd *pUnused; /* Unused file descriptors to close */ UnixUnusedFd *pUnused; /* Unused file descriptors to close */
unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ unixInodeInfo *pNext; /* List of all unixInodeInfo objects */
unixInodeInfo *pPrev; /* .... doubly linked */ unixInodeInfo *pPrev; /* .... doubly linked */
#if defined(SQLITE_ENABLE_LOCKING_STYLE) #if SQLITE_ENABLE_LOCKING_STYLE
unsigned long long sharedByte; /* for AFP simulated shared lock */ unsigned long long sharedByte; /* for AFP simulated shared lock */
#endif #endif
#if OS_VXWORKS #if OS_VXWORKS
@ -3086,7 +3090,7 @@ static int unixWrite(
SimulateDiskfullError(( wrote=0, amt=1 )); SimulateDiskfullError(( wrote=0, amt=1 ));
if( amt>0 ){ if( amt>0 ){
if( wrote<0 ){ if( wrote<0 && pFile->lastErrno!=ENOSPC ){
/* lastErrno set by seekAndWrite */ /* lastErrno set by seekAndWrite */
return SQLITE_IOERR_WRITE; return SQLITE_IOERR_WRITE;
}else{ }else{
@ -3911,7 +3915,7 @@ static int unixShmMap(
MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion
); );
if( pMem==MAP_FAILED ){ if( pMem==MAP_FAILED ){
rc = SQLITE_IOERR; rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
goto shmpage_out; goto shmpage_out;
} }
}else{ }else{
@ -6682,6 +6686,10 @@ int sqlite3_os_init(void){
}; };
unsigned int i; /* Loop counter */ unsigned int i; /* Loop counter */
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==16 );
/* Register all VFSes defined in the aVfs[] array */ /* Register all VFSes defined in the aVfs[] array */
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
sqlite3_vfs_register(&aVfs[i], i==0); sqlite3_vfs_register(&aVfs[i], i==0);

View File

@ -118,6 +118,7 @@ struct winFile {
#endif #endif
}; };
/* /*
** Forward prototypes. ** Forward prototypes.
*/ */
@ -298,6 +299,109 @@ static char *utf8ToMbcs(const char *zFilename){
return zFilenameMbcs; return zFilenameMbcs;
} }
/*
** The return value of getLastErrorMsg
** is zero if the error message fits in the buffer, or non-zero
** otherwise (if the message was truncated).
*/
static int getLastErrorMsg(int nBuf, char *zBuf){
/* FormatMessage returns 0 on failure. Otherwise it
** returns the number of TCHARs written to the output
** buffer, excluding the terminating null char.
*/
DWORD error = GetLastError();
DWORD dwLen = 0;
char *zOut = 0;
if( isNT() ){
WCHAR *zTempWide = NULL;
dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
0,
(LPWSTR) &zTempWide,
0,
0);
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
zOut = unicodeToUtf8(zTempWide);
/* free the system buffer allocated by FormatMessage */
LocalFree(zTempWide);
}
/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
** Since the ASCII version of these Windows API do not exist for WINCE,
** it's important to not reference them for WINCE builds.
*/
#if SQLITE_OS_WINCE==0
}else{
char *zTemp = NULL;
dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
0,
(LPSTR) &zTemp,
0,
0);
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
/* free the system buffer allocated by FormatMessage */
LocalFree(zTemp);
}
#endif
}
if( 0 == dwLen ){
sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
}else{
/* copy a maximum of nBuf chars to output buffer */
sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
/* free the UTF8 buffer */
free(zOut);
}
return 0;
}
/*
**
** This function - winLogErrorAtLine() - is only ever called via the macro
** winLogError().
**
** This routine is invoked after an error occurs in an OS function.
** It logs a message using sqlite3_log() containing the current value of
** error code and, if possible, the human-readable equivalent from
** FormatMessage.
**
** The first argument passed to the macro should be the error code that
** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN).
** The two subsequent arguments should be the name of the OS function that
** failed and the the associated file-system path, if any.
*/
#define winLogError(a,b,c) winLogErrorAtLine(a,b,c,__LINE__)
static int winLogErrorAtLine(
int errcode, /* SQLite error code */
const char *zFunc, /* Name of OS function that failed */
const char *zPath, /* File path associated with error */
int iLine /* Source line number where error occurred */
){
char zMsg[500]; /* Human readable error text */
int i; /* Loop counter */
DWORD iErrno = GetLastError(); /* Error code */
zMsg[0] = 0;
getLastErrorMsg(sizeof(zMsg), zMsg);
assert( errcode!=SQLITE_OK );
if( zPath==0 ) zPath = "";
for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
zMsg[i] = 0;
sqlite3_log(errcode,
"os_win.c:%d: (%d) %s(%s) - %s",
iLine, iErrno, zFunc, zPath, zMsg
);
return errcode;
}
#if SQLITE_OS_WINCE #if SQLITE_OS_WINCE
/************************************************************************* /*************************************************************************
** This section contains code for WinCE only. ** This section contains code for WinCE only.
@ -375,6 +479,7 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
pFile->hMutex = CreateMutexW(NULL, FALSE, zName); pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
if (!pFile->hMutex){ if (!pFile->hMutex){
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
winLogError(SQLITE_ERROR, "winceCreateLock1", zFilename);
free(zName); free(zName);
return FALSE; return FALSE;
} }
@ -406,6 +511,7 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
/* If mapping failed, close the shared memory handle and erase it */ /* If mapping failed, close the shared memory handle and erase it */
if (!pFile->shared){ if (!pFile->shared){
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
winLogError(SQLITE_ERROR, "winceCreateLock2", zFilename);
CloseHandle(pFile->hShared); CloseHandle(pFile->hShared);
pFile->hShared = NULL; pFile->hShared = NULL;
} }
@ -651,6 +757,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){ if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
winLogError(SQLITE_IOERR_SEEK, "seekWinFile", pFile->zPath);
return 1; return 1;
} }
@ -696,7 +803,8 @@ static int winClose(sqlite3_file *id){
#endif #endif
OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
OpenCounter(-1); OpenCounter(-1);
return rc ? SQLITE_OK : SQLITE_IOERR; return rc ? SQLITE_OK
: winLogError(SQLITE_IOERR_CLOSE, "winClose", pFile->zPath);
} }
/* /*
@ -722,7 +830,7 @@ static int winRead(
} }
if( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ if( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
return SQLITE_IOERR_READ; return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath);
} }
if( nRead<(DWORD)amt ){ if( nRead<(DWORD)amt ){
/* Unread parts of the buffer must be zero-filled */ /* Unread parts of the buffer must be zero-filled */
@ -773,7 +881,7 @@ static int winWrite(
if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){ if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
return SQLITE_FULL; return SQLITE_FULL;
} }
return SQLITE_IOERR_WRITE; return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath);
} }
return SQLITE_OK; return SQLITE_OK;
} }
@ -801,10 +909,10 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
/* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
if( seekWinFile(pFile, nByte) ){ if( seekWinFile(pFile, nByte) ){
rc = SQLITE_IOERR_TRUNCATE; rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate1", pFile->zPath);
}else if( 0==SetEndOfFile(pFile->h) ){ }else if( 0==SetEndOfFile(pFile->h) ){
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
rc = SQLITE_IOERR_TRUNCATE; rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate2", pFile->zPath);
} }
OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok")); OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
@ -826,6 +934,7 @@ int sqlite3_fullsync_count = 0;
static int winSync(sqlite3_file *id, int flags){ static int winSync(sqlite3_file *id, int flags){
#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || defined(SQLITE_DEBUG) #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || defined(SQLITE_DEBUG)
winFile *pFile = (winFile*)id; winFile *pFile = (winFile*)id;
BOOL rc;
#else #else
UNUSED_PARAMETER(id); UNUSED_PARAMETER(id);
#endif #endif
@ -838,20 +947,19 @@ static int winSync(sqlite3_file *id, int flags){
OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype)); OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype));
#ifndef SQLITE_TEST
UNUSED_PARAMETER(flags);
#else
if( flags & SQLITE_SYNC_FULL ){
sqlite3_fullsync_count++;
}
sqlite3_sync_count++;
#endif
/* Unix cannot, but some systems may return SQLITE_FULL from here. This /* Unix cannot, but some systems may return SQLITE_FULL from here. This
** line is to test that doing so does not cause any problems. ** line is to test that doing so does not cause any problems.
*/ */
SimulateDiskfullError( return SQLITE_FULL ); SimulateDiskfullError( return SQLITE_FULL );
SimulateIOError( return SQLITE_IOERR; );
#ifndef SQLITE_TEST
UNUSED_PARAMETER(flags);
#else
if( (flags&0x0F)==SQLITE_SYNC_FULL ){
sqlite3_fullsync_count++;
}
sqlite3_sync_count++;
#endif
/* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
** no-op ** no-op
@ -859,11 +967,13 @@ static int winSync(sqlite3_file *id, int flags){
#ifdef SQLITE_NO_SYNC #ifdef SQLITE_NO_SYNC
return SQLITE_OK; return SQLITE_OK;
#else #else
if( FlushFileBuffers(pFile->h) ){ rc = FlushFileBuffers(pFile->h);
SimulateIOError( rc=FALSE );
if( rc ){
return SQLITE_OK; return SQLITE_OK;
}else{ }else{
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
return SQLITE_IOERR; return winLogError(SQLITE_IOERR_FSYNC, "winSync", pFile->zPath);
} }
#endif #endif
} }
@ -884,7 +994,7 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
&& ((error = GetLastError()) != NO_ERROR) ) && ((error = GetLastError()) != NO_ERROR) )
{ {
pFile->lastErrno = error; pFile->lastErrno = error;
return SQLITE_IOERR_FSTAT; return winLogError(SQLITE_IOERR_FSTAT, "winFileSize", pFile->zPath);
} }
*pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
return SQLITE_OK; return SQLITE_OK;
@ -923,6 +1033,7 @@ static int getReadLock(winFile *pFile){
} }
if( res == 0 ){ if( res == 0 ){
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
/* No need to log a failure to lock */
} }
return res; return res;
} }
@ -943,6 +1054,7 @@ static int unlockReadLock(winFile *pFile){
} }
if( res == 0 ){ if( res == 0 ){
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
winLogError(SQLITE_IOERR_UNLOCK, "unlockReadLock", pFile->zPath);
} }
return res; return res;
} }
@ -1143,7 +1255,7 @@ static int winUnlock(sqlite3_file *id, int locktype){
if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
/* This should never happen. We should always be able to /* This should never happen. We should always be able to
** reacquire the read lock */ ** reacquire the read lock */
rc = SQLITE_IOERR_UNLOCK; rc = winLogError(SQLITE_IOERR_UNLOCK, "winUnlock", pFile->zPath);
} }
} }
if( type>=RESERVED_LOCK ){ if( type>=RESERVED_LOCK ){
@ -1500,7 +1612,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
rc = SQLITE_IOERR_SHMOPEN; rc = winLogError(SQLITE_IOERR_SHMOPEN, "winOpenShm", pDbFd->zPath);
} }
} }
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
@ -1759,7 +1871,7 @@ static int winShmMap(
*/ */
rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
rc = SQLITE_IOERR_SHMSIZE; rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap1", pDbFd->zPath);
goto shmpage_out; goto shmpage_out;
} }
@ -1773,7 +1885,7 @@ static int winShmMap(
if( !isWrite ) goto shmpage_out; if( !isWrite ) goto shmpage_out;
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
rc = SQLITE_IOERR_SHMSIZE; rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap2", pDbFd->zPath);
goto shmpage_out; goto shmpage_out;
} }
} }
@ -1810,7 +1922,7 @@ static int winShmMap(
} }
if( !pMap ){ if( !pMap ){
pShmNode->lastErrno = GetLastError(); pShmNode->lastErrno = GetLastError();
rc = SQLITE_IOERR; rc = winLogError(SQLITE_IOERR_SHMMAP, "winShmMap3", pDbFd->zPath);
if( hMap ) CloseHandle(hMap); if( hMap ) CloseHandle(hMap);
goto shmpage_out; goto shmpage_out;
} }
@ -1972,68 +2084,6 @@ static int getTempname(int nBuf, char *zBuf){
return SQLITE_OK; return SQLITE_OK;
} }
/*
** The return value of getLastErrorMsg
** is zero if the error message fits in the buffer, or non-zero
** otherwise (if the message was truncated).
*/
static int getLastErrorMsg(int nBuf, char *zBuf){
/* FormatMessage returns 0 on failure. Otherwise it
** returns the number of TCHARs written to the output
** buffer, excluding the terminating null char.
*/
DWORD error = GetLastError();
DWORD dwLen = 0;
char *zOut = 0;
if( isNT() ){
WCHAR *zTempWide = NULL;
dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
0,
(LPWSTR) &zTempWide,
0,
0);
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
zOut = unicodeToUtf8(zTempWide);
/* free the system buffer allocated by FormatMessage */
LocalFree(zTempWide);
}
/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
** Since the ASCII version of these Windows API do not exist for WINCE,
** it's important to not reference them for WINCE builds.
*/
#if SQLITE_OS_WINCE==0
}else{
char *zTemp = NULL;
dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
0,
(LPSTR) &zTemp,
0,
0);
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
/* free the system buffer allocated by FormatMessage */
LocalFree(zTemp);
}
#endif
}
if( 0 == dwLen ){
sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
}else{
/* copy a maximum of nBuf chars to output buffer */
sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
/* free the UTF8 buffer */
free(zOut);
}
return 0;
}
/* /*
** Open a file. ** Open a file.
*/ */
@ -2205,6 +2255,7 @@ static int winOpen(
if( h==INVALID_HANDLE_VALUE ){ if( h==INVALID_HANDLE_VALUE ){
pFile->lastErrno = GetLastError(); pFile->lastErrno = GetLastError();
winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name);
free(zConverted); free(zConverted);
if( isReadWrite ){ if( isReadWrite ){
return winOpen(pVfs, zName, id, return winOpen(pVfs, zName, id,
@ -2308,7 +2359,8 @@ static int winDelete(
"ok" : "failed" )); "ok" : "failed" ));
return ( (rc == INVALID_FILE_ATTRIBUTES) return ( (rc == INVALID_FILE_ATTRIBUTES)
&& (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE; && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK :
winLogError(SQLITE_IOERR_DELETE, "winDelete", zFilename);
} }
/* /*
@ -2348,6 +2400,7 @@ static int winAccess(
} }
}else{ }else{
if( GetLastError()!=ERROR_FILE_NOT_FOUND ){ if( GetLastError()!=ERROR_FILE_NOT_FOUND ){
winLogError(SQLITE_IOERR_ACCESS, "winAccess", zFilename);
free(zConverted); free(zConverted);
return SQLITE_IOERR_ACCESS; return SQLITE_IOERR_ACCESS;
}else{ }else{

View File

@ -4239,11 +4239,13 @@ int sqlite3Select(
** and pKeyInfo to the KeyInfo structure required to navigate the ** and pKeyInfo to the KeyInfo structure required to navigate the
** index. ** index.
** **
** (2011-04-15) Do not do a full scan of an unordered index.
**
** In practice the KeyInfo structure will not be used. It is only ** In practice the KeyInfo structure will not be used. It is only
** passed to keep OP_OpenRead happy. ** passed to keep OP_OpenRead happy.
*/ */
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( !pBest || pIdx->nColumn<pBest->nColumn ){ if( pIdx->bUnordered==0 && (!pBest || pIdx->nColumn<pBest->nColumn) ){
pBest = pIdx; pBest = pIdx;
} }
} }

View File

@ -71,6 +71,9 @@ extern int isatty();
#define isatty(x) 1 #define isatty(x) 1
#endif #endif
/* True if the timer is enabled */
static int enableTimer = 0;
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
@ -78,9 +81,6 @@ extern int isatty();
/* Saved resource information for the beginning of an operation */ /* Saved resource information for the beginning of an operation */
static struct rusage sBegin; static struct rusage sBegin;
/* True if the timer is enabled */
static int enableTimer = 0;
/* /*
** Begin timing an operation ** Begin timing an operation
*/ */
@ -124,9 +124,6 @@ static FILETIME ftUserBegin;
typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
static GETPROCTIMES getProcessTimesAddr = NULL; static GETPROCTIMES getProcessTimesAddr = NULL;
/* True if the timer is enabled */
static int enableTimer = 0;
/* /*
** Check to see if we have timer support. Return 1 if necessary ** Check to see if we have timer support. Return 1 if necessary
** support found (or found previously). ** support found (or found previously).

View File

@ -447,6 +447,8 @@ int sqlite3_exec(
#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))

View File

@ -26,8 +26,8 @@
*/ */
#ifdef SQLITE_COVERAGE_TEST #ifdef SQLITE_COVERAGE_TEST
void sqlite3Coverage(int x){ void sqlite3Coverage(int x){
static int dummy = 0; static unsigned dummy = 0;
dummy += x; dummy += (unsigned)x;
} }
#endif #endif

View File

@ -17,175 +17,181 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
source $testdir/lock_common.tcl source $testdir/lock_common.tcl
set testprefix exists
# This block of tests is targeted at CREATE XXX IF NOT EXISTS statements. foreach jm {rollback wal} {
#
do_multiclient_test tn {
# TABLE objects. set testprefix exists-$jm
# This block of tests is targeted at CREATE XXX IF NOT EXISTS statements.
# #
do_test 1.$tn.1.1 { do_multiclient_test tn {
sql2 { CREATE TABLE t1(x) }
sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
sql2 { DROP TABLE t1 }
sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
} {t1}
do_test 1.$tn.1.2 { # TABLE objects.
sql2 { CREATE TABLE t2(x) } #
sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 } do_test 1.$tn.1.1 {
sql2 { DROP TABLE t2 } if {$jm == "wal"} { sql2 { PRAGMA journal_mode = WAL } }
sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 } sql2 { CREATE TABLE t1(x) }
sql2 { SELECT name FROM sqlite_master WHERE type = 'table' } sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
} {t1 t2} sql2 { DROP TABLE t1 }
sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
} {t1}
do_test 1.$tn.1.2 {
sql2 { CREATE TABLE t2(x) }
sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 }
sql2 { DROP TABLE t2 }
sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 }
sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
} {t1 t2}
# INDEX objects. # INDEX objects.
#
do_test 1.$tn.2 {
sql2 { CREATE INDEX i1 ON t1(a) }
sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
sql2 { DROP INDEX i1 }
sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
} {i1}
# VIEW objects.
#
do_test 1.$tn.3 {
sql2 { CREATE VIEW v1 AS SELECT * FROM t1 }
sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
sql2 { DROP VIEW v1 }
sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
} {v1}
# TRIGGER objects.
#
do_test $tn.4 {
sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
sql2 { DROP TRIGGER tr1 }
sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
} {tr1}
}
# This block of tests is targeted at DROP XXX IF EXISTS statements.
# #
do_test 1.$tn.2 { do_multiclient_test tn {
sql2 { CREATE INDEX i1 ON t1(a) }
sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
sql2 { DROP INDEX i1 }
sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
} {i1}
# VIEW objects. # TABLE objects.
#
do_test 2.$tn.1 {
if {$jm == "wal"} { sql1 { PRAGMA journal_mode = WAL } }
sql1 { DROP TABLE IF EXISTS t1 }
sql2 { CREATE TABLE t1(x) }
sql1 { DROP TABLE IF EXISTS t1 }
sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
} {}
# INDEX objects.
#
do_test 2.$tn.2 {
sql1 { CREATE TABLE t2(x) }
sql1 { DROP INDEX IF EXISTS i2 }
sql2 { CREATE INDEX i2 ON t2(x) }
sql1 { DROP INDEX IF EXISTS i2 }
sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
} {}
# VIEW objects.
#
do_test 2.$tn.3 {
sql1 { DROP VIEW IF EXISTS v1 }
sql2 { CREATE VIEW v1 AS SELECT * FROM t2 }
sql1 { DROP VIEW IF EXISTS v1 }
sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
} {}
# TRIGGER objects.
#
do_test 2.$tn.4 {
sql1 { DROP TRIGGER IF EXISTS tr1 }
sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
sql1 { DROP TRIGGER IF EXISTS tr1 }
sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
} {}
}
# This block of tests is targeted at DROP XXX IF EXISTS statements with
# attached databases.
# #
do_test 1.$tn.3 { do_multiclient_test tn {
sql2 { CREATE VIEW v1 AS SELECT * FROM t1 }
sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
sql2 { DROP VIEW v1 }
sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
} {v1}
# TRIGGER objects. forcedelete test.db2
# do_test 3.$tn.0 {
do_test $tn.4 { sql1 { ATTACH 'test.db2' AS aux }
sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END } sql2 { ATTACH 'test.db2' AS aux }
sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END } } {}
sql2 { DROP TRIGGER tr1 }
sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
} {tr1}
}
# This block of tests is targeted at DROP XXX IF EXISTS statements. # TABLE objects.
# #
do_multiclient_test tn { do_test 3.$tn.1.1 {
sql1 { DROP TABLE IF EXISTS aux.t1 }
sql2 { CREATE TABLE aux.t1(x) }
sql1 { DROP TABLE IF EXISTS aux.t1 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
} {}
do_test 3.$tn.1.2 {
sql1 { DROP TABLE IF EXISTS t1 }
sql2 { CREATE TABLE aux.t1(x) }
sql1 { DROP TABLE IF EXISTS t1 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
} {}
# TABLE objects. # INDEX objects.
# #
do_test 2.$tn.1 { do_test 3.$tn.2.1 {
sql1 { DROP TABLE IF EXISTS t1 } sql1 { CREATE TABLE aux.t2(x) }
sql2 { CREATE TABLE t1(x) } sql1 { DROP INDEX IF EXISTS aux.i2 }
sql1 { DROP TABLE IF EXISTS t1 } sql2 { CREATE INDEX aux.i2 ON t2(x) }
sql2 { SELECT name FROM sqlite_master WHERE type = 'table' } sql1 { DROP INDEX IF EXISTS aux.i2 }
} {} sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
} {}
do_test 3.$tn.2.2 {
sql1 { DROP INDEX IF EXISTS i2 }
sql2 { CREATE INDEX aux.i2 ON t2(x) }
sql1 { DROP INDEX IF EXISTS i2 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
} {}
# INDEX objects. # VIEW objects.
# #
do_test 2.$tn.2 { do_test 3.$tn.3.1 {
sql1 { CREATE TABLE t2(x) } sql1 { DROP VIEW IF EXISTS aux.v1 }
sql1 { DROP INDEX IF EXISTS i2 } sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
sql2 { CREATE INDEX i2 ON t2(x) } sql1 { DROP VIEW IF EXISTS aux.v1 }
sql1 { DROP INDEX IF EXISTS i2 } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
sql2 { SELECT name FROM sqlite_master WHERE type = 'index' } } {}
} {} do_test 3.$tn.3.2 {
sql1 { DROP VIEW IF EXISTS v1 }
sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
sql1 { DROP VIEW IF EXISTS v1 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
} {}
# VIEW objects. # TRIGGER objects.
# #
do_test 2.$tn.3 { do_test 3.$tn.4.1 {
sql1 { DROP VIEW IF EXISTS v1 } sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
sql2 { CREATE VIEW v1 AS SELECT * FROM t2 } sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
sql1 { DROP VIEW IF EXISTS v1 } sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
sql2 { SELECT name FROM sqlite_master WHERE type = 'view' } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
} {} } {}
do_test 3.$tn.4.2 {
# TRIGGER objects. sql1 { DROP TRIGGER IF EXISTS tr1 }
# sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
do_test 2.$tn.4 { sql1 { DROP TRIGGER IF EXISTS tr1 }
sql1 { DROP TRIGGER IF EXISTS tr1 } sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END } } {}
sql1 { DROP TRIGGER IF EXISTS tr1 } }
sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
} {}
}
# This block of tests is targeted at DROP XXX IF EXISTS statements with
# attached databases.
#
do_multiclient_test tn {
forcedelete test.db2
do_test 3.$tn.0 {
sql1 { ATTACH 'test.db2' AS aux }
sql2 { ATTACH 'test.db2' AS aux }
} {}
# TABLE objects.
#
do_test 3.$tn.1.1 {
sql1 { DROP TABLE IF EXISTS aux.t1 }
sql2 { CREATE TABLE aux.t1(x) }
sql1 { DROP TABLE IF EXISTS aux.t1 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
} {}
do_test 3.$tn.1.2 {
sql1 { DROP TABLE IF EXISTS t1 }
sql2 { CREATE TABLE aux.t1(x) }
sql1 { DROP TABLE IF EXISTS t1 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
} {}
# INDEX objects.
#
do_test 3.$tn.2.1 {
sql1 { CREATE TABLE aux.t2(x) }
sql1 { DROP INDEX IF EXISTS aux.i2 }
sql2 { CREATE INDEX aux.i2 ON t2(x) }
sql1 { DROP INDEX IF EXISTS aux.i2 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
} {}
do_test 3.$tn.2.2 {
sql1 { DROP INDEX IF EXISTS i2 }
sql2 { CREATE INDEX aux.i2 ON t2(x) }
sql1 { DROP INDEX IF EXISTS i2 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
} {}
# VIEW objects.
#
do_test 3.$tn.3.1 {
sql1 { DROP VIEW IF EXISTS aux.v1 }
sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
sql1 { DROP VIEW IF EXISTS aux.v1 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
} {}
do_test 3.$tn.3.2 {
sql1 { DROP VIEW IF EXISTS v1 }
sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
sql1 { DROP VIEW IF EXISTS v1 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
} {}
# TRIGGER objects.
#
do_test 3.$tn.4.1 {
sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
} {}
do_test 3.$tn.4.2 {
sql1 { DROP TRIGGER IF EXISTS tr1 }
sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
sql1 { DROP TRIGGER IF EXISTS tr1 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
} {}
} }

View File

@ -202,6 +202,9 @@ do_test quota-3.2.9 {
set ::quota [list] set ::quota [list]
proc quota_callback {file limitvar size} { proc quota_callback {file limitvar size} {
upvar $limitvar limit upvar $limitvar limit
if {$::tcl_platform(platform)=="windows"} {
set file [ lindex [string map {\\ \/} $file] 0 ]
}
lappend ::quota $file $size lappend ::quota $file $size
set limit 0 set limit 0
} }

View File

@ -19,19 +19,27 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# #
# These tests are only applicable on unix when pager pragma are # These tests are only applicable when pager pragma are
# enabled. Also, since every test uses an ATTACHed database, they # enabled. Also, since every test uses an ATTACHed database, they
# are only run when ATTACH is enabled. # are only run when ATTACH is enabled.
# #
if {$::tcl_platform(platform)!="unix"} {
finish_test
return
}
ifcapable !pager_pragmas||!attach { ifcapable !pager_pragmas||!attach {
finish_test finish_test
return return
} }
set sqlite_sync_count 0
proc cond_incr_sync_count {adj} {
global sqlite_sync_count
if {$::tcl_platform(platform) == "windows"} {
incr sqlite_sync_count $adj
} {
ifcapable !dirsync {
incr sqlite_sync_count $adj
}
}
}
do_test sync-1.1 { do_test sync-1.1 {
set sqlite_sync_count 0 set sqlite_sync_count 0
file delete -force test2.db file delete -force test2.db
@ -42,9 +50,7 @@ do_test sync-1.1 {
ATTACH DATABASE 'test2.db' AS db2; ATTACH DATABASE 'test2.db' AS db2;
CREATE TABLE db2.t2(x,y); CREATE TABLE db2.t2(x,y);
} }
ifcapable !dirsync { cond_incr_sync_count 2
incr sqlite_sync_count 2
}
set sqlite_sync_count set sqlite_sync_count
} 8 } 8
ifcapable pager_pragmas { ifcapable pager_pragmas {
@ -58,9 +64,7 @@ ifcapable pager_pragmas {
INSERT INTO t2 VALUES(3,4); INSERT INTO t2 VALUES(3,4);
COMMIT; COMMIT;
} }
ifcapable !dirsync { cond_incr_sync_count 3
incr sqlite_sync_count 3
}
set sqlite_sync_count set sqlite_sync_count
} 8 } 8
} }
@ -74,9 +78,7 @@ do_test sync-1.3 {
INSERT INTO t2 VALUES(5,6); INSERT INTO t2 VALUES(5,6);
COMMIT; COMMIT;
} }
ifcapable !dirsync { cond_incr_sync_count 3
incr sqlite_sync_count 3
}
set sqlite_sync_count set sqlite_sync_count
} 10 } 10
ifcapable pager_pragmas { ifcapable pager_pragmas {

View File

@ -246,7 +246,7 @@ do_test triggerC-2.2 {
} {100} } {100}
do_test triggerC-2.3 { do_test triggerC-2.3 {
execsql { execsql "
CREATE TABLE t23(x PRIMARY KEY); CREATE TABLE t23(x PRIMARY KEY);
CREATE TRIGGER t23a AFTER INSERT ON t23 BEGIN CREATE TRIGGER t23a AFTER INSERT ON t23 BEGIN
@ -254,15 +254,15 @@ do_test triggerC-2.3 {
END; END;
CREATE TRIGGER t23b BEFORE INSERT ON t23 BEGIN CREATE TRIGGER t23b BEFORE INSERT ON t23 BEGIN
SELECT CASE WHEN new.x>500 SELECT CASE WHEN new.x>[expr $SQLITE_MAX_TRIGGER_DEPTH / 2]
THEN RAISE(IGNORE) THEN RAISE(IGNORE)
ELSE NULL END; ELSE NULL END;
END; END;
INSERT INTO t23 VALUES(1); INSERT INTO t23 VALUES(1);
SELECT count(*) FROM t23; SELECT count(*) FROM t23;
} "
} {500} } [list [expr $SQLITE_MAX_TRIGGER_DEPTH / 2]]
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
@ -288,12 +288,12 @@ do_test triggerC-3.1.3 {
} {} } {}
do_test triggerC-3.2.1 { do_test triggerC-3.2.1 {
execsql { execsql "
CREATE TABLE t3b(x); CREATE TABLE t3b(x);
CREATE TRIGGER t3bi AFTER INSERT ON t3b WHEN new.x<2000 BEGIN CREATE TRIGGER t3bi AFTER INSERT ON t3b WHEN new.x<[expr $SQLITE_MAX_TRIGGER_DEPTH * 2] BEGIN
INSERT INTO t3b VALUES(new.x+1); INSERT INTO t3b VALUES(new.x+1);
END; END;
} "
catchsql { catchsql {
INSERT INTO t3b VALUES(1); INSERT INTO t3b VALUES(1);
} }
@ -303,39 +303,39 @@ do_test triggerC-3.2.2 {
} {} } {}
do_test triggerC-3.3.1 { do_test triggerC-3.3.1 {
catchsql { catchsql "
INSERT INTO t3b VALUES(1001); INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH + 1]);
} "
} {0 {}} } {0 {}}
do_test triggerC-3.3.2 { do_test triggerC-3.3.2 {
db eval {SELECT count(*), max(x), min(x) FROM t3b} db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {1000 2000 1001} } [list $SQLITE_MAX_TRIGGER_DEPTH [expr $SQLITE_MAX_TRIGGER_DEPTH * 2] [expr $SQLITE_MAX_TRIGGER_DEPTH + 1]]
do_test triggerC-3.4.1 { do_test triggerC-3.4.1 {
catchsql { catchsql "
DELETE FROM t3b; DELETE FROM t3b;
INSERT INTO t3b VALUES(999); INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH - 1]);
} "
} {1 {too many levels of trigger recursion}} } {1 {too many levels of trigger recursion}}
do_test triggerC-3.4.2 { do_test triggerC-3.4.2 {
db eval {SELECT count(*), max(x), min(x) FROM t3b} db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {0 {} {}} } {0 {} {}}
do_test triggerC-3.5.1 { do_test triggerC-3.5.1 {
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 100 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH [expr $SQLITE_MAX_TRIGGER_DEPTH / 10]
catchsql { catchsql "
INSERT INTO t3b VALUES(1901); INSERT INTO t3b VALUES([expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - ($SQLITE_MAX_TRIGGER_DEPTH / 10) + 1]);
} "
} {0 {}} } {0 {}}
do_test triggerC-3.5.2 { do_test triggerC-3.5.2 {
db eval {SELECT count(*), max(x), min(x) FROM t3b} db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {100 2000 1901} } [list [expr $SQLITE_MAX_TRIGGER_DEPTH / 10] [expr $SQLITE_MAX_TRIGGER_DEPTH * 2] [expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - ($SQLITE_MAX_TRIGGER_DEPTH / 10) + 1]]
do_test triggerC-3.5.3 { do_test triggerC-3.5.3 {
catchsql { catchsql "
DELETE FROM t3b; DELETE FROM t3b;
INSERT INTO t3b VALUES(1900); INSERT INTO t3b VALUES([expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - ($SQLITE_MAX_TRIGGER_DEPTH / 10)]);
} "
} {1 {too many levels of trigger recursion}} } {1 {too many levels of trigger recursion}}
do_test triggerC-3.5.4 { do_test triggerC-3.5.4 {
db eval {SELECT count(*), max(x), min(x) FROM t3b} db eval {SELECT count(*), max(x), min(x) FROM t3b}
@ -343,25 +343,25 @@ do_test triggerC-3.5.4 {
do_test triggerC-3.6.1 { do_test triggerC-3.6.1 {
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1
catchsql { catchsql "
INSERT INTO t3b VALUES(2000); INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH * 2]);
} "
} {0 {}} } {0 {}}
do_test triggerC-3.6.2 { do_test triggerC-3.6.2 {
db eval {SELECT count(*), max(x), min(x) FROM t3b} db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {1 2000 2000} } [list 1 [expr $SQLITE_MAX_TRIGGER_DEPTH * 2] [expr $SQLITE_MAX_TRIGGER_DEPTH * 2]]
do_test triggerC-3.6.3 { do_test triggerC-3.6.3 {
catchsql { catchsql "
DELETE FROM t3b; DELETE FROM t3b;
INSERT INTO t3b VALUES(1999); INSERT INTO t3b VALUES([expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - 1]);
} "
} {1 {too many levels of trigger recursion}} } {1 {too many levels of trigger recursion}}
do_test triggerC-3.6.4 { do_test triggerC-3.6.4 {
db eval {SELECT count(*), max(x), min(x) FROM t3b} db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {0 {} {}} } {0 {} {}}
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH $SQLITE_MAX_TRIGGER_DEPTH
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# This next block of tests, triggerC-4.*, checks that affinity # This next block of tests, triggerC-4.*, checks that affinity

68
test/unordered.test Normal file
View File

@ -0,0 +1,68 @@
# 2011 April 9
#
# 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.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix unordered
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES(1, 'xxx');
INSERT INTO t1 SELECT a+1, b FROM t1;
INSERT INTO t1 SELECT a+2, 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;
ANALYZE;
} {}
foreach idxmode {ordered unordered} {
if {$idxmode == "unordered"} {
execsql { UPDATE sqlite_stat1 SET stat = stat || ' unordered' }
db close
sqlite3 db test.db
}
foreach {tn sql r(ordered) r(unordered)} {
1 "SELECT * FROM t1 ORDER BY a"
{0 0 0 {SCAN TABLE t1 USING INDEX i1 (~128 rows)}}
{0 0 0 {SCAN TABLE t1 (~128 rows)} 0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
2 "SELECT * FROM t1 WHERE a >?"
{0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?) (~32 rows)}}
{0 0 0 {SCAN TABLE t1 (~42 rows)}}
3 "SELECT * FROM t1 WHERE a = ? ORDER BY rowid"
{0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~1 rows)}}
{0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~1 rows)}
0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
4 "SELECT max(a) FROM t1"
{0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (~1 rows)}}
{0 0 0 {SEARCH TABLE t1 (~1 rows)}}
5 "SELECT group_concat(b) FROM t1 GROUP BY a"
{0 0 0 {SCAN TABLE t1 USING INDEX i1 (~128 rows)}}
{0 0 0 {SCAN TABLE t1 (~128 rows)} 0 0 0 {USE TEMP B-TREE FOR GROUP BY}}
6 "SELECT * FROM t1 WHERE a = ?"
{0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~1 rows)}}
{0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~1 rows)}}
7 "SELECT count(*) FROM t1"
{0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1(~128 rows)}}
{0 0 0 {SCAN TABLE t1 (~128 rows)}}
} {
do_eqp_test 1.$idxmode.$tn $sql $r($idxmode)
}
}
finish_test

View File

@ -23,6 +23,18 @@ set testprefix wal2
ifcapable !wal {finish_test ; return } ifcapable !wal {finish_test ; return }
set sqlite_sync_count 0
proc cond_incr_sync_count {adj} {
global sqlite_sync_count
if {$::tcl_platform(platform) == "windows"} {
incr sqlite_sync_count $adj
} {
ifcapable !dirsync {
incr sqlite_sync_count $adj
}
}
}
proc set_tvfs_hdr {file args} { proc set_tvfs_hdr {file args} {
# Set $nHdr to the number of bytes in the wal-index header: # Set $nHdr to the number of bytes in the wal-index header:
@ -1189,6 +1201,7 @@ foreach {tn sql reslist} {
} {10 0 5 5 0 2 2} } {10 0 5 5 0 2 2}
do_test wal2-14.$tn.3 { do_test wal2-14.$tn.3 {
cond_incr_sync_count 1
list $sqlite_sync_count $sqlite_fullsync_count list $sqlite_sync_count $sqlite_fullsync_count
} [lrange $reslist 0 1] } [lrange $reslist 0 1]

155
tool/rollback-test.c Normal file
View File

@ -0,0 +1,155 @@
/*
** This program is used to generate and verify databases with hot journals.
** Use this program to generate a hot journal on one machine and verify
** that it rolls back correctly on another machine with a different
** architecture.
**
** Usage:
**
** rollback-test new [-utf8] [-utf16le] [-utf16be] [-pagesize=N] DATABASE
** rollback-test check DATABASE
** rollback-test crash [-wal] [-rollback] DATABASE
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"
static void usage(char *argv0){
fprintf(stderr,
"Usage: %s new [-utf8] [-utf16le] [-utf16be] [-pagesize=N] DATABASE\n"
" %s check DATABASE\n"
" %s crash [-wal] DATABASE\n",
argv0, argv0, argv0
);
exit(1);
}
static sqlite3 *openDb(const char *zFilename){
int rc;
sqlite3 *db;
rc = sqlite3_open(zFilename, &db);
if( rc ){
fprintf(stderr, "Cannot open \"%s\": %s\n",
zFilename, sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
return db;
}
static int nReply = 0;
static char zReply[1000];
static int execCallback(void *NotUsed, int nArg, char **azArg, char **azCol){
int i, n;
char *z;
for(i=0; i<nArg; i++){
z = azArg[i];
if( z==0 ) z = "NULL";
if( nReply>0 && nReply<sizeof(zReply)-1 ) zReply[nReply++] = ' ';
n = strlen(z);
if( nReply+n>=sizeof(zReply)-1 ) n = sizeof(zReply) - nReply - 1;
memcpy(&zReply[nReply], z, n);
nReply += n;
zReply[nReply] = 0;
}
return 0;
}
static void runSql(sqlite3 *db, const char *zSql){
char *zErr = 0;
int rc;
nReply = 0;
rc = sqlite3_exec(db, zSql, execCallback, 0, &zErr);
if( zErr ){
fprintf(stderr, "SQL error: %s\n", zErr);
exit(1);
}
if( rc ){
fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
exit(1);
}
}
int main(int argc, char **argv){
sqlite3 *db;
int i;
if( argc<3 ) usage(argv[0]);
if( strcmp(argv[1], "new")==0 ){
db = openDb(argv[argc-1]);
for(i=2; i<argc-1; i++){
if( strcmp(argv[i],"-utf8")==0 ){
runSql(db, "PRAGMA encoding=UTF8");
}else if( strcmp(argv[i], "-utf16le")==0 ){
runSql(db, "PRAGMA encoding=UTF16LE");
}else if( strcmp(argv[i], "-utf16be")==0 ){
runSql(db, "PRAGMA encoding=UTF16BE");
}else if( strncmp(argv[i], "-pagesize=", 10)==0 ){
int szPg = atoi(&argv[i][10]);
char zBuf[100];
sprintf(zBuf, "PRAGMA pagesize=%d", szPg);
runSql(db, zBuf);
}else{
fprintf(stderr, "unknown option %s\n", argv[i]);
usage(argv[0]);
}
}
runSql(db,
"BEGIN;"
"CREATE TABLE t1(x INTEGER PRIMARY KEY, y);"
"INSERT INTO t1(y) VALUES('abcdefghijklmnopqrstuvwxyz');"
"INSERT INTO t1(y) VALUES('abcdefghijklmnopqrstuvwxyz');"
"INSERT INTO t1(y) SELECT y FROM t1;" /* 4 */
"INSERT INTO t1(y) SELECT y FROM t1;" /* 8 */
"INSERT INTO t1(y) SELECT y FROM t1;" /* 16 */
"INSERT INTO t1(y) SELECT y FROM t1;" /* 32 */
"INSERT INTO t1(y) SELECT y FROM t1;" /* 64 */
"INSERT INTO t1(y) SELECT y FROM t1;" /* 128 */
"INSERT INTO t1(y) SELECT y FROM t1;" /* 256 */
"INSERT INTO t1(y) SELECT y FROM t1;" /* 512 */
"INSERT INTO t1(y) SELECT y FROM t1;" /* 1024 */
"UPDATE t1 SET y=(y || x);"
"CREATE INDEX t1y ON t1(y);"
"COMMIT;"
);
sqlite3_close(db);
}else if( strcmp(argv[1], "check")==0 ){
db = openDb(argv[argc-1]);
runSql(db, "PRAGMA integrity_check");
if( strcmp(zReply, "ok")!=0 ){
fprintf(stderr, "Integrity check: %s\n", zReply);
exit(1);
}
runSql(db,
"SELECT count(*) FROM t1 WHERE y<>('abcdefghijklmnopqrstuvwxyz' || x)"
);
if( strcmp(zReply, "0")!=0 ){
fprintf(stderr, "Wrong content\n");
exit(1);
}
printf("Ok\n");
}else if( strcmp(argv[1], "crash")==0 ){
db = openDb(argv[argc-1]);
for(i=2; i<argc-1; i++){
if( strcmp(argv[i],"-wal")==0 ){
runSql(db, "PRAGMA journal_mode=WAL");
}else if( strcmp(argv[i], "-rollback")==0 ){
runSql(db, "PRAGMA journal_mode=DELETE");
}else{
fprintf(stderr, "unknown option %s\n", argv[i]);
usage(argv[0]);
}
}
runSql(db,
"PRAGMA cache_size=10;"
"BEGIN;"
"UPDATE t1 SET y=(y || -x)"
);
exit(0);
}else{
usage(argv[0]);
}
return 0;
}

View File

@ -200,7 +200,7 @@ do_test shell1-1.15.3 {
# -version show SQLite version # -version show SQLite version
do_test shell1-1.16.1 { do_test shell1-1.16.1 {
catchcmd "-version test.db" "" catchcmd "-version test.db" ""
} {0 3.7.6} } {0 3.7.6.1}
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Test cases shell1-2.*: Basic "dot" command token parsing. # Test cases shell1-2.*: Basic "dot" command token parsing.

View File

@ -464,7 +464,7 @@ static void usage(const char *argv0){
" NNNbc Decode btree page NNN and show content\n" " NNNbc Decode btree page NNN and show content\n"
" NNNbm Decode btree page NNN and show a layout map\n" " NNNbm Decode btree page NNN and show a layout map\n"
" NNNt Decode freelist trunk page NNN\n" " NNNt Decode freelist trunk page NNN\n"
" NNNtd Show leave freelist pages on the decode\n" " NNNtd Show leaf freelist pages on the decode\n"
" NNNtr Recurisvely decode freelist starting at NNN\n" " NNNtr Recurisvely decode freelist starting at NNN\n"
); );
} }