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:
18
configure
vendored
18
configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# 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,
|
||||
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.7.6'
|
||||
PACKAGE_STRING='sqlite 3.7.6'
|
||||
PACKAGE_VERSION='3.7.6.1'
|
||||
PACKAGE_STRING='sqlite 3.7.6.1'
|
||||
PACKAGE_BUGREPORT=''
|
||||
|
||||
# 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.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
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]...
|
||||
|
||||
@ -1550,7 +1550,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
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
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1666,7 +1666,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.7.6
|
||||
sqlite configure 3.7.6.1
|
||||
generated by GNU Autoconf 2.62
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
$ $0 $@
|
||||
@ -13942,7 +13942,7 @@ exec 6>&1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
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
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -13995,7 +13995,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
||||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
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,
|
||||
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
48
manifest
48
manifest
@ -1,11 +1,11 @@
|
||||
C Fix\sfurther\smissing\scomments\sand\sother\sminor\sissues\sin\sthe\ssession\smodule\scode.
|
||||
D 2011-04-18T15:47:08.694
|
||||
C Merge\strunk\schanges\sinto\ssessions\sbranch.
|
||||
D 2011-04-18T17:30:56.521
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.vxworks c85ec1d8597fe2f7bc225af12ac1666e21379151
|
||||
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
|
||||
F VERSION d1056b26608c9a2695187d57cac12ae89492639d
|
||||
F VERSION c97e5dcdea2407f4a94f9740294cdf39ce9e88c4
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
|
||||
F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248
|
||||
@ -22,7 +22,7 @@ F art/src_logo.gif 9341ef09f0e53cd44c0c9b6fc3c16f7f3d6c2ad9
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 868fdb48c028421a203470e15c69ada15b9ba673
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure c38c1947db7ed4adaed2affcb09cea9d3acd5a9a x
|
||||
F configure 61dbf78cdc4d6a871333dc599c130be6cce865c5 x
|
||||
F configure.ac 87a3c71bbe9c925381c154413eea7f3cdc397244
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
|
||||
@ -154,7 +154,7 @@ F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
||||
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
|
||||
F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85
|
||||
F src/main.c 8b97db74cb876bf34ca4fb3720b18e4ffdcf9fd5
|
||||
F src/malloc.c 788f2ed928786dfe305b6783d551d6b1a9080976
|
||||
F src/malloc.c 74c740e8ba22b806cfb980c8c0ddea1cbd54a20e
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
|
||||
F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf
|
||||
@ -164,16 +164,16 @@ F src/memjournal.c 0ebce851677a7ac035ba1512a7e65851b34530c6
|
||||
F src/mutex.c 6949180803ff05a7d0e2b9334a95b4fb5a00e23f
|
||||
F src/mutex.h fe2ef5e1c4dae531d5a544f9241f19c56d26803d
|
||||
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_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33
|
||||
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
||||
F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d
|
||||
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
|
||||
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
|
||||
F src/os_os2.c 2596fd2d5d0976c6c0c628d0c3c7c4e7a724f4cf
|
||||
F src/os_unix.c a8fe62148d41e54e383d3360a711a01595feef58
|
||||
F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845
|
||||
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
|
||||
F src/os_unix.c d7889a0f9389c8c2e1d3b380f5aa1256c22a90e8
|
||||
F src/os_win.c d149b9a7dfdd38de09afc054f8168cd3cd80630b
|
||||
F src/pager.c 055239dcdfe12b3f5d97f6f01f85da01e2d6d912
|
||||
F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1
|
||||
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
||||
@ -186,9 +186,9 @@ F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
|
||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||
F src/select.c 649a6f10f7eb7b52a5a28847773cb9968a828ae8
|
||||
F src/shell.c 9c8389796764f65d4506bcd614ac8061f4160d5c
|
||||
F src/sqlite.h.in 9cff46ef60540f044c1b665db606aa63ba67048f
|
||||
F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff
|
||||
F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79
|
||||
F src/sqlite.h.in 0cf61c41c48e1e6b863ff8cf9ecd69620932330e
|
||||
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
|
||||
F src/sqliteInt.h 9a29e5bb82f3abef6b4af91e18d637050fa3c883
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
@ -243,7 +243,7 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080
|
||||
F src/trigger.c 144cc18bb701f3286484aae4292a9531f09278c8
|
||||
F src/update.c 3f3f3bb734a0da1dffd0ed33e504642b35ed3605
|
||||
F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60
|
||||
F src/util.c cd997077bad039efc0597eb027c929658f93c018
|
||||
F src/util.c 465fe10aabf0ca7d7826a156dab919b0b65c525a
|
||||
F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e
|
||||
F src/vdbe.c dd53dda1cf786397e72643a497b5c2f368ff11ba
|
||||
F src/vdbe.h 44fd57aeed86da0cd31206626c13cdde0e72cc0e
|
||||
@ -398,7 +398,7 @@ F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
|
||||
F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062
|
||||
F test/exclusive2.test 343d55130c12c67b8bf10407acec043a6c26c86b
|
||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/exists.test 81363f6982ea49dfd820a50845466390e60a4a0c
|
||||
F test/exists.test 5e2d64b4eb5a9d08876599bdae2e1213d2d12e2a
|
||||
F test/expr.test 19e8ac40313e2282a47b586d11c4892040990d3a
|
||||
F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
|
||||
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
|
||||
@ -623,7 +623,7 @@ F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
|
||||
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
||||
F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8
|
||||
F test/quota.test 48c3a5a98687d67ef06fc16d2e603284756bbec3
|
||||
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
||||
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
|
||||
F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a
|
||||
@ -688,7 +688,7 @@ F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796
|
||||
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
F test/superlock.test 5d7a4954b0059c903f82c7b67867bc5451a7c082
|
||||
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
|
||||
F test/sync.test 2bd73b585089c99e76b3e1796c42059b7d89d872
|
||||
F test/syscall.test 707c95e4ab7863e13f1293c6b0c76bead30249b3
|
||||
F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f
|
||||
F test/table.test 04ba066432430657712d167ebf28080fe878d305
|
||||
@ -838,7 +838,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
|
||||
F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31
|
||||
F test/triggerA.test eaf11a29db2a11967d2d4b49d37f92bce598194e
|
||||
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
|
||||
F test/triggerC.test 8a691ff6dd47df2e57395bbec4b62101fac0f363
|
||||
F test/triggerC.test 811ab569af9e6fc894afbcc0d77d14500b2406c5
|
||||
F test/triggerD.test c6add3817351451e419f6ff9e9a259b02b6e2de7
|
||||
F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af
|
||||
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
|
||||
@ -846,6 +846,7 @@ F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84
|
||||
F test/types3.test a0f66bf12f80fad89493535474f7a6d16fa58150
|
||||
F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2
|
||||
F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e
|
||||
F test/unordered.test e81169ce2a8f31b2c6b66af691887e1376ab3ced
|
||||
F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172
|
||||
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
|
||||
F test/vacuum.test 29b60e8cc9e573b39676df6c4a75fe9e02d04a09
|
||||
@ -873,7 +874,7 @@ F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
|
||||
F test/wal.test 5617ad308bfdb8a8885220d8a261a6096a8d7e57
|
||||
F test/wal2.test e561a8c6fdd1c2cd1876f3e39757934e7b7361f8
|
||||
F test/wal2.test aa0fb2314b3235be4503c06873e41ebfc0757782
|
||||
F test/wal3.test 5c396cc22497244d627306f4c1d360167353f8dd
|
||||
F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
|
||||
F test/wal5.test 1bbfaa316dc2a1d0d1fac3f4500c38a90055a41b
|
||||
@ -920,12 +921,13 @@ F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
|
||||
F tool/omittest.tcl b1dd290c1596e0f31fd335160a74ec5dfea3df4a
|
||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||
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/shell3.test 4fad469e8003938426355afdf34155f08c587836
|
||||
F tool/shell4.test 35f9c3d452b4e76d5013c63e1fd07478a62f14ce
|
||||
F tool/shell5.test 62bfaf9267296da1b91e4b1c03e44e7b393f6a94
|
||||
F tool/showdb.c 471c0f8fa472e71bb7654500096a5bdb4ea1fb2a
|
||||
F tool/showdb.c 43e913d954684c2f5007dcab46d1a1308852a0ad
|
||||
F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02
|
||||
F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9
|
||||
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
||||
@ -938,7 +940,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P 20d7c280235201e519f296372f269e7cecda24da
|
||||
R 22fa2c52781f892ef560f2c8f63b1707
|
||||
P 99f0f35092b0b78b7016b21c242da263ab64b77b 3e135748f1efacb52b414b3ac3f4ae2c08bcd8fb
|
||||
R b2692e50ee7820b096983b9aa33c1efd
|
||||
U dan
|
||||
Z e6f0d0d675f579cb5b46b0fe2c73f457
|
||||
Z c7fa020efb14904762c294d2eedf7456
|
||||
|
@ -1 +1 @@
|
||||
99f0f35092b0b78b7016b21c242da263ab64b77b
|
||||
b91b4c31fe311b292044c9c747feba294ffce25c
|
11
src/malloc.c
11
src/malloc.c
@ -266,7 +266,7 @@ static int mallocWithAlarm(int n, void **pp){
|
||||
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
|
||||
if( mem0.alarmCallback!=0 ){
|
||||
int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
if( nUsed+nFull >= mem0.alarmThreshold ){
|
||||
if( nUsed >= mem0.alarmThreshold - nFull ){
|
||||
mem0.nearlyFull = 1;
|
||||
sqlite3MallocAlarm(nFull);
|
||||
}else{
|
||||
@ -507,7 +507,7 @@ void sqlite3DbFree(sqlite3 *db, void *p){
|
||||
** Change the size of an existing memory allocation
|
||||
*/
|
||||
void *sqlite3Realloc(void *pOld, int nBytes){
|
||||
int nOld, nNew;
|
||||
int nOld, nNew, nDiff;
|
||||
void *pNew;
|
||||
if( pOld==0 ){
|
||||
return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
|
||||
@ -530,8 +530,9 @@ void *sqlite3Realloc(void *pOld, int nBytes){
|
||||
}else if( sqlite3GlobalConfig.bMemstat ){
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
|
||||
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >=
|
||||
mem0.alarmThreshold ){
|
||||
nDiff = nNew - nOld;
|
||||
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
|
||||
mem0.alarmThreshold-nDiff ){
|
||||
sqlite3MallocAlarm(nNew-nOld);
|
||||
}
|
||||
assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
|
||||
@ -543,7 +544,7 @@ void *sqlite3Realloc(void *pOld, int nBytes){
|
||||
}
|
||||
if( pNew ){
|
||||
nNew = sqlite3MallocSize(pNew);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
|
||||
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nDiff);
|
||||
}
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
}else{
|
||||
|
@ -251,7 +251,7 @@ static void os2MutexLeave(sqlite3_mutex *p){
|
||||
#endif
|
||||
}
|
||||
|
||||
SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
|
||||
sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
|
||||
static const sqlite3_mutex_methods sMutex = {
|
||||
os2MutexInit,
|
||||
os2MutexEnd,
|
||||
|
1080
src/os_os2.c
1080
src/os_os2.c
File diff suppressed because it is too large
Load Diff
@ -293,7 +293,7 @@ static struct unix_syscall {
|
||||
sqlite3_syscall_ptr pDefault; /* Default value */
|
||||
} aSyscall[] = {
|
||||
{ "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 },
|
||||
#define osClose ((int(*)(int))aSyscall[1].pCurrent)
|
||||
@ -330,7 +330,7 @@ static struct unix_syscall {
|
||||
{ "read", (sqlite3_syscall_ptr)read, 0 },
|
||||
#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 },
|
||||
#else
|
||||
{ "pread", (sqlite3_syscall_ptr)0, 0 },
|
||||
@ -347,7 +347,7 @@ static struct unix_syscall {
|
||||
{ "write", (sqlite3_syscall_ptr)write, 0 },
|
||||
#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 },
|
||||
#else
|
||||
{ "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))\
|
||||
aSyscall[13].pCurrent)
|
||||
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
|
||||
#else
|
||||
{ "fchmod", (sqlite3_syscall_ptr)0, 0 },
|
||||
#endif
|
||||
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
|
||||
|
||||
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
|
||||
@ -929,7 +933,7 @@ struct unixInodeInfo {
|
||||
UnixUnusedFd *pUnused; /* Unused file descriptors to close */
|
||||
unixInodeInfo *pNext; /* List of all unixInodeInfo objects */
|
||||
unixInodeInfo *pPrev; /* .... doubly linked */
|
||||
#if defined(SQLITE_ENABLE_LOCKING_STYLE)
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
unsigned long long sharedByte; /* for AFP simulated shared lock */
|
||||
#endif
|
||||
#if OS_VXWORKS
|
||||
@ -3086,7 +3090,7 @@ static int unixWrite(
|
||||
SimulateDiskfullError(( wrote=0, amt=1 ));
|
||||
|
||||
if( amt>0 ){
|
||||
if( wrote<0 ){
|
||||
if( wrote<0 && pFile->lastErrno!=ENOSPC ){
|
||||
/* lastErrno set by seekAndWrite */
|
||||
return SQLITE_IOERR_WRITE;
|
||||
}else{
|
||||
@ -3911,7 +3915,7 @@ static int unixShmMap(
|
||||
MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion
|
||||
);
|
||||
if( pMem==MAP_FAILED ){
|
||||
rc = SQLITE_IOERR;
|
||||
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
|
||||
goto shmpage_out;
|
||||
}
|
||||
}else{
|
||||
@ -6682,6 +6686,10 @@ int sqlite3_os_init(void){
|
||||
};
|
||||
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 */
|
||||
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
|
||||
sqlite3_vfs_register(&aVfs[i], i==0);
|
||||
|
225
src/os_win.c
225
src/os_win.c
@ -118,6 +118,7 @@ struct winFile {
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Forward prototypes.
|
||||
*/
|
||||
@ -298,6 +299,109 @@ static char *utf8ToMbcs(const char *zFilename){
|
||||
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
|
||||
/*************************************************************************
|
||||
** 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);
|
||||
if (!pFile->hMutex){
|
||||
pFile->lastErrno = GetLastError();
|
||||
winLogError(SQLITE_ERROR, "winceCreateLock1", zFilename);
|
||||
free(zName);
|
||||
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 (!pFile->shared){
|
||||
pFile->lastErrno = GetLastError();
|
||||
winLogError(SQLITE_ERROR, "winceCreateLock2", zFilename);
|
||||
CloseHandle(pFile->hShared);
|
||||
pFile->hShared = NULL;
|
||||
}
|
||||
@ -651,6 +757,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
|
||||
dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
|
||||
if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){
|
||||
pFile->lastErrno = GetLastError();
|
||||
winLogError(SQLITE_IOERR_SEEK, "seekWinFile", pFile->zPath);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -696,7 +803,8 @@ static int winClose(sqlite3_file *id){
|
||||
#endif
|
||||
OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
|
||||
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) ){
|
||||
pFile->lastErrno = GetLastError();
|
||||
return SQLITE_IOERR_READ;
|
||||
return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath);
|
||||
}
|
||||
if( nRead<(DWORD)amt ){
|
||||
/* Unread parts of the buffer must be zero-filled */
|
||||
@ -773,7 +881,7 @@ static int winWrite(
|
||||
if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
|
||||
return SQLITE_FULL;
|
||||
}
|
||||
return SQLITE_IOERR_WRITE;
|
||||
return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath);
|
||||
}
|
||||
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. */
|
||||
if( seekWinFile(pFile, nByte) ){
|
||||
rc = SQLITE_IOERR_TRUNCATE;
|
||||
rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate1", pFile->zPath);
|
||||
}else if( 0==SetEndOfFile(pFile->h) ){
|
||||
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"));
|
||||
@ -826,6 +934,7 @@ int sqlite3_fullsync_count = 0;
|
||||
static int winSync(sqlite3_file *id, int flags){
|
||||
#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || defined(SQLITE_DEBUG)
|
||||
winFile *pFile = (winFile*)id;
|
||||
BOOL rc;
|
||||
#else
|
||||
UNUSED_PARAMETER(id);
|
||||
#endif
|
||||
@ -838,20 +947,19 @@ static int winSync(sqlite3_file *id, int flags){
|
||||
|
||||
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
|
||||
** line is to test that doing so does not cause any problems.
|
||||
*/
|
||||
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
|
||||
** no-op
|
||||
@ -859,11 +967,13 @@ static int winSync(sqlite3_file *id, int flags){
|
||||
#ifdef SQLITE_NO_SYNC
|
||||
return SQLITE_OK;
|
||||
#else
|
||||
if( FlushFileBuffers(pFile->h) ){
|
||||
rc = FlushFileBuffers(pFile->h);
|
||||
SimulateIOError( rc=FALSE );
|
||||
if( rc ){
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
pFile->lastErrno = GetLastError();
|
||||
return SQLITE_IOERR;
|
||||
return winLogError(SQLITE_IOERR_FSYNC, "winSync", pFile->zPath);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -884,7 +994,7 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
|
||||
&& ((error = GetLastError()) != NO_ERROR) )
|
||||
{
|
||||
pFile->lastErrno = error;
|
||||
return SQLITE_IOERR_FSTAT;
|
||||
return winLogError(SQLITE_IOERR_FSTAT, "winFileSize", pFile->zPath);
|
||||
}
|
||||
*pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
|
||||
return SQLITE_OK;
|
||||
@ -923,6 +1033,7 @@ static int getReadLock(winFile *pFile){
|
||||
}
|
||||
if( res == 0 ){
|
||||
pFile->lastErrno = GetLastError();
|
||||
/* No need to log a failure to lock */
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -943,6 +1054,7 @@ static int unlockReadLock(winFile *pFile){
|
||||
}
|
||||
if( res == 0 ){
|
||||
pFile->lastErrno = GetLastError();
|
||||
winLogError(SQLITE_IOERR_UNLOCK, "unlockReadLock", pFile->zPath);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -1143,7 +1255,7 @@ static int winUnlock(sqlite3_file *id, int locktype){
|
||||
if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
|
||||
/* This should never happen. We should always be able to
|
||||
** reacquire the read lock */
|
||||
rc = SQLITE_IOERR_UNLOCK;
|
||||
rc = winLogError(SQLITE_IOERR_UNLOCK, "winUnlock", pFile->zPath);
|
||||
}
|
||||
}
|
||||
if( type>=RESERVED_LOCK ){
|
||||
@ -1500,7 +1612,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
|
||||
if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
|
||||
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
rc = SQLITE_IOERR_SHMOPEN;
|
||||
rc = winLogError(SQLITE_IOERR_SHMOPEN, "winOpenShm", pDbFd->zPath);
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
@ -1759,7 +1871,7 @@ static int winShmMap(
|
||||
*/
|
||||
rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
|
||||
if( rc!=SQLITE_OK ){
|
||||
rc = SQLITE_IOERR_SHMSIZE;
|
||||
rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap1", pDbFd->zPath);
|
||||
goto shmpage_out;
|
||||
}
|
||||
|
||||
@ -1773,7 +1885,7 @@ static int winShmMap(
|
||||
if( !isWrite ) goto shmpage_out;
|
||||
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
|
||||
if( rc!=SQLITE_OK ){
|
||||
rc = SQLITE_IOERR_SHMSIZE;
|
||||
rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap2", pDbFd->zPath);
|
||||
goto shmpage_out;
|
||||
}
|
||||
}
|
||||
@ -1810,7 +1922,7 @@ static int winShmMap(
|
||||
}
|
||||
if( !pMap ){
|
||||
pShmNode->lastErrno = GetLastError();
|
||||
rc = SQLITE_IOERR;
|
||||
rc = winLogError(SQLITE_IOERR_SHMMAP, "winShmMap3", pDbFd->zPath);
|
||||
if( hMap ) CloseHandle(hMap);
|
||||
goto shmpage_out;
|
||||
}
|
||||
@ -1972,68 +2084,6 @@ static int getTempname(int nBuf, char *zBuf){
|
||||
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.
|
||||
*/
|
||||
@ -2205,6 +2255,7 @@ static int winOpen(
|
||||
|
||||
if( h==INVALID_HANDLE_VALUE ){
|
||||
pFile->lastErrno = GetLastError();
|
||||
winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name);
|
||||
free(zConverted);
|
||||
if( isReadWrite ){
|
||||
return winOpen(pVfs, zName, id,
|
||||
@ -2308,7 +2359,8 @@ static int winDelete(
|
||||
"ok" : "failed" ));
|
||||
|
||||
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{
|
||||
if( GetLastError()!=ERROR_FILE_NOT_FOUND ){
|
||||
winLogError(SQLITE_IOERR_ACCESS, "winAccess", zFilename);
|
||||
free(zConverted);
|
||||
return SQLITE_IOERR_ACCESS;
|
||||
}else{
|
||||
|
@ -4239,11 +4239,13 @@ int sqlite3Select(
|
||||
** and pKeyInfo to the KeyInfo structure required to navigate the
|
||||
** 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
|
||||
** passed to keep OP_OpenRead happy.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,9 @@ extern int isatty();
|
||||
#define isatty(x) 1
|
||||
#endif
|
||||
|
||||
/* True if the timer is enabled */
|
||||
static int enableTimer = 0;
|
||||
|
||||
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
@ -78,9 +81,6 @@ extern int isatty();
|
||||
/* Saved resource information for the beginning of an operation */
|
||||
static struct rusage sBegin;
|
||||
|
||||
/* True if the timer is enabled */
|
||||
static int enableTimer = 0;
|
||||
|
||||
/*
|
||||
** Begin timing an operation
|
||||
*/
|
||||
@ -124,9 +124,6 @@ static FILETIME ftUserBegin;
|
||||
typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
|
||||
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
|
||||
** support found (or found previously).
|
||||
|
@ -447,6 +447,8 @@ int sqlite3_exec(
|
||||
#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8))
|
||||
#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<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_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
|
||||
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
|
||||
|
@ -26,8 +26,8 @@
|
||||
*/
|
||||
#ifdef SQLITE_COVERAGE_TEST
|
||||
void sqlite3Coverage(int x){
|
||||
static int dummy = 0;
|
||||
dummy += x;
|
||||
static unsigned dummy = 0;
|
||||
dummy += (unsigned)x;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
316
test/exists.test
316
test/exists.test
@ -17,175 +17,181 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
|
||||
set testprefix exists
|
||||
|
||||
# This block of tests is targeted at CREATE XXX IF NOT EXISTS statements.
|
||||
#
|
||||
do_multiclient_test tn {
|
||||
foreach jm {rollback wal} {
|
||||
|
||||
# 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 {
|
||||
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_multiclient_test tn {
|
||||
|
||||
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}
|
||||
# TABLE objects.
|
||||
#
|
||||
do_test 1.$tn.1.1 {
|
||||
if {$jm == "wal"} { sql2 { PRAGMA journal_mode = WAL } }
|
||||
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 {
|
||||
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 {
|
||||
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}
|
||||
do_multiclient_test tn {
|
||||
|
||||
# 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 {
|
||||
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}
|
||||
do_multiclient_test tn {
|
||||
|
||||
# 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}
|
||||
}
|
||||
forcedelete test.db2
|
||||
do_test 3.$tn.0 {
|
||||
sql1 { ATTACH 'test.db2' AS aux }
|
||||
sql2 { ATTACH 'test.db2' AS aux }
|
||||
} {}
|
||||
|
||||
# This block of tests is targeted at DROP XXX IF EXISTS statements.
|
||||
#
|
||||
do_multiclient_test tn {
|
||||
# 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' }
|
||||
} {}
|
||||
|
||||
# TABLE objects.
|
||||
#
|
||||
do_test 2.$tn.1 {
|
||||
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 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' }
|
||||
} {}
|
||||
|
||||
# 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 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' }
|
||||
} {}
|
||||
|
||||
# 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_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' }
|
||||
} {}
|
||||
# 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' }
|
||||
} {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -202,6 +202,9 @@ do_test quota-3.2.9 {
|
||||
set ::quota [list]
|
||||
proc quota_callback {file limitvar size} {
|
||||
upvar $limitvar limit
|
||||
if {$::tcl_platform(platform)=="windows"} {
|
||||
set file [ lindex [string map {\\ \/} $file] 0 ]
|
||||
}
|
||||
lappend ::quota $file $size
|
||||
set limit 0
|
||||
}
|
||||
|
@ -19,19 +19,27 @@ set testdir [file dirname $argv0]
|
||||
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
|
||||
# are only run when ATTACH is enabled.
|
||||
#
|
||||
if {$::tcl_platform(platform)!="unix"} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
ifcapable !pager_pragmas||!attach {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_test sync-1.1 {
|
||||
set sqlite_sync_count 0
|
||||
file delete -force test2.db
|
||||
@ -42,9 +50,7 @@ do_test sync-1.1 {
|
||||
ATTACH DATABASE 'test2.db' AS db2;
|
||||
CREATE TABLE db2.t2(x,y);
|
||||
}
|
||||
ifcapable !dirsync {
|
||||
incr sqlite_sync_count 2
|
||||
}
|
||||
cond_incr_sync_count 2
|
||||
set sqlite_sync_count
|
||||
} 8
|
||||
ifcapable pager_pragmas {
|
||||
@ -58,9 +64,7 @@ ifcapable pager_pragmas {
|
||||
INSERT INTO t2 VALUES(3,4);
|
||||
COMMIT;
|
||||
}
|
||||
ifcapable !dirsync {
|
||||
incr sqlite_sync_count 3
|
||||
}
|
||||
cond_incr_sync_count 3
|
||||
set sqlite_sync_count
|
||||
} 8
|
||||
}
|
||||
@ -74,9 +78,7 @@ do_test sync-1.3 {
|
||||
INSERT INTO t2 VALUES(5,6);
|
||||
COMMIT;
|
||||
}
|
||||
ifcapable !dirsync {
|
||||
incr sqlite_sync_count 3
|
||||
}
|
||||
cond_incr_sync_count 3
|
||||
set sqlite_sync_count
|
||||
} 10
|
||||
ifcapable pager_pragmas {
|
||||
|
@ -246,7 +246,7 @@ do_test triggerC-2.2 {
|
||||
} {100}
|
||||
|
||||
do_test triggerC-2.3 {
|
||||
execsql {
|
||||
execsql "
|
||||
CREATE TABLE t23(x PRIMARY KEY);
|
||||
|
||||
CREATE TRIGGER t23a AFTER INSERT ON t23 BEGIN
|
||||
@ -254,15 +254,15 @@ do_test triggerC-2.3 {
|
||||
END;
|
||||
|
||||
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)
|
||||
ELSE NULL END;
|
||||
END;
|
||||
|
||||
INSERT INTO t23 VALUES(1);
|
||||
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 {
|
||||
execsql {
|
||||
execsql "
|
||||
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);
|
||||
END;
|
||||
}
|
||||
"
|
||||
catchsql {
|
||||
INSERT INTO t3b VALUES(1);
|
||||
}
|
||||
@ -303,39 +303,39 @@ do_test triggerC-3.2.2 {
|
||||
} {}
|
||||
|
||||
do_test triggerC-3.3.1 {
|
||||
catchsql {
|
||||
INSERT INTO t3b VALUES(1001);
|
||||
}
|
||||
catchsql "
|
||||
INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH + 1]);
|
||||
"
|
||||
} {0 {}}
|
||||
do_test triggerC-3.3.2 {
|
||||
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 {
|
||||
catchsql {
|
||||
catchsql "
|
||||
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}}
|
||||
do_test triggerC-3.4.2 {
|
||||
db eval {SELECT count(*), max(x), min(x) FROM t3b}
|
||||
} {0 {} {}}
|
||||
|
||||
do_test triggerC-3.5.1 {
|
||||
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 100
|
||||
catchsql {
|
||||
INSERT INTO t3b VALUES(1901);
|
||||
}
|
||||
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH [expr $SQLITE_MAX_TRIGGER_DEPTH / 10]
|
||||
catchsql "
|
||||
INSERT INTO t3b VALUES([expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - ($SQLITE_MAX_TRIGGER_DEPTH / 10) + 1]);
|
||||
"
|
||||
} {0 {}}
|
||||
do_test triggerC-3.5.2 {
|
||||
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 {
|
||||
catchsql {
|
||||
catchsql "
|
||||
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}}
|
||||
do_test triggerC-3.5.4 {
|
||||
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 {
|
||||
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1
|
||||
catchsql {
|
||||
INSERT INTO t3b VALUES(2000);
|
||||
}
|
||||
catchsql "
|
||||
INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH * 2]);
|
||||
"
|
||||
} {0 {}}
|
||||
do_test triggerC-3.6.2 {
|
||||
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 {
|
||||
catchsql {
|
||||
catchsql "
|
||||
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}}
|
||||
do_test triggerC-3.6.4 {
|
||||
db eval {SELECT count(*), max(x), min(x) FROM t3b}
|
||||
} {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
|
||||
|
68
test/unordered.test
Normal file
68
test/unordered.test
Normal 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
|
@ -23,6 +23,18 @@ set testprefix wal2
|
||||
|
||||
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} {
|
||||
|
||||
# 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}
|
||||
|
||||
do_test wal2-14.$tn.3 {
|
||||
cond_incr_sync_count 1
|
||||
list $sqlite_sync_count $sqlite_fullsync_count
|
||||
} [lrange $reslist 0 1]
|
||||
|
||||
|
155
tool/rollback-test.c
Normal file
155
tool/rollback-test.c
Normal 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;
|
||||
}
|
@ -200,7 +200,7 @@ do_test shell1-1.15.3 {
|
||||
# -version show SQLite version
|
||||
do_test shell1-1.16.1 {
|
||||
catchcmd "-version test.db" ""
|
||||
} {0 3.7.6}
|
||||
} {0 3.7.6.1}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Test cases shell1-2.*: Basic "dot" command token parsing.
|
||||
|
@ -464,7 +464,7 @@ static void usage(const char *argv0){
|
||||
" NNNbc Decode btree page NNN and show content\n"
|
||||
" NNNbm Decode btree page NNN and show a layout map\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"
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user