mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Merge recent enhancements, and especially the WAL overwrite change, from trunk.
FossilOrigin-Name: c4a858b228a164be2f89f5b01833f0b5e0d7735b
This commit is contained in:
18
configure
vendored
18
configure
vendored
@ -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.69 for sqlite 3.10.0.
|
# Generated by GNU Autoconf 2.69 for sqlite 3.11.0.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||||
@ -726,8 +726,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='sqlite'
|
PACKAGE_NAME='sqlite'
|
||||||
PACKAGE_TARNAME='sqlite'
|
PACKAGE_TARNAME='sqlite'
|
||||||
PACKAGE_VERSION='3.10.0'
|
PACKAGE_VERSION='3.11.0'
|
||||||
PACKAGE_STRING='sqlite 3.10.0'
|
PACKAGE_STRING='sqlite 3.11.0'
|
||||||
PACKAGE_BUGREPORT=''
|
PACKAGE_BUGREPORT=''
|
||||||
PACKAGE_URL=''
|
PACKAGE_URL=''
|
||||||
|
|
||||||
@ -1460,7 +1460,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.10.0 to adapt to many kinds of systems.
|
\`configure' configures sqlite 3.11.0 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@ -1525,7 +1525,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.10.0:";;
|
short | recursive ) echo "Configuration of sqlite 3.11.0:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@ -1646,7 +1646,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.10.0
|
sqlite configure 3.11.0
|
||||||
generated by GNU Autoconf 2.69
|
generated by GNU Autoconf 2.69
|
||||||
|
|
||||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
@ -2065,7 +2065,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.10.0, which was
|
It was created by sqlite $as_me 3.11.0, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
@ -12023,7 +12023,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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.10.0, which was
|
This file was extended by sqlite $as_me 3.11.0, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@ -12089,7 +12089,7 @@ _ACEOF
|
|||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
sqlite config.status 3.10.0
|
sqlite config.status 3.11.0
|
||||||
configured by $0, generated by GNU Autoconf 2.69,
|
configured by $0, generated by GNU Autoconf 2.69,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
55
manifest
55
manifest
@ -1,10 +1,10 @@
|
|||||||
C Merge\schanges\sfor\sversion\s3.10.0.
|
C Merge\srecent\senhancements,\sand\sespecially\sthe\sWAL\soverwrite\schange,\sfrom\strunk.
|
||||||
D 2016-01-06T15:14:53.379
|
D 2016-01-11T13:10:41.337
|
||||||
F Makefile.in e3c1e13b4eba06cbb7f9295148383b7e284596be
|
F Makefile.in e3c1e13b4eba06cbb7f9295148383b7e284596be
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc 6862a51bfd3716bbe3c387c724feb73937b107d2
|
F Makefile.msc 6862a51bfd3716bbe3c387c724feb73937b107d2
|
||||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||||
F VERSION 8b9d3ac6f1962f94e06ba05462422a544f9c4e36
|
F VERSION 866588d1edf0ccb5b0d33896974338f97564f719
|
||||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||||
@ -29,7 +29,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
|||||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||||
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
|
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
|
||||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||||
F configure e511ceefe595e35051933a90c848ab4fa1d48add x
|
F configure b4519bb54fff37e7cde9d03d8f2946f18d5d0086 x
|
||||||
F configure.ac fcfc67b323d32daaa3e46cf7782d9465ed423a6d
|
F configure.ac fcfc67b323d32daaa3e46cf7782d9465ed423a6d
|
||||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||||
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
||||||
@ -295,21 +295,21 @@ F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395
|
|||||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||||
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
|
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
|
||||||
F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf
|
F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf
|
||||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
|
||||||
F src/btree.c 4d3452b2a3daf875490ac4f0a278da7f85fabe12
|
F src/btree.c 6bd9b3d778a023e2238a81cd0b87b00085220e0e
|
||||||
F src/btree.h 2d76dee44704c47eed323356a758662724b674a0
|
F src/btree.h 68ef301795e00cdf1d3ab93abc44a43b7fe771e0
|
||||||
F src/btreeInt.h b5f2651b41808f038dee9282c5dc0232ce6532d3
|
F src/btreeInt.h b5f2651b41808f038dee9282c5dc0232ce6532d3
|
||||||
F src/build.c d8006e9030c61b9495d0b2f724edd3fcdae16930
|
F src/build.c 9d497ff4bf3c82cecb520436e0e9963785627583
|
||||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||||
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||||
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
||||||
F src/date.c e4655393bb403fa310eef66cc4583d75d4d7fd93
|
F src/date.c e4655393bb403fa310eef66cc4583d75d4d7fd93
|
||||||
F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
|
F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
|
||||||
F src/delete.c 86e3940d07fe69a40270c2aaf6ca6c7adf19246c
|
F src/delete.c 86e3940d07fe69a40270c2aaf6ca6c7adf19246c
|
||||||
F src/expr.c 38790e65d1219f2b7dc26458f39a5252fe7c60cd
|
F src/expr.c fe55c489362d1429c364e98c877514f4455f45a6
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c e18b3dff7d47c7bcac5ac4fc178a89b9fd322b44
|
F src/fkey.c e18b3dff7d47c7bcac5ac4fc178a89b9fd322b44
|
||||||
F src/func.c cf5e10af9125b245f1b962e8ba4d520a37818795
|
F src/func.c ccaf46fa98f795673afbfab73dff7c18db88f3cd
|
||||||
F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260
|
F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260
|
||||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||||
@ -324,7 +324,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
|||||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||||
F src/mem5.c 262055c242fa7db59c5f07ad77fdc4e97888c054
|
F src/mem5.c 71f81a11fc5e29a57428761ab38a7bf2ef4ee19d
|
||||||
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
|
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
|
||||||
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
|
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
|
||||||
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
|
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
|
||||||
@ -337,14 +337,14 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
|
|||||||
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
||||||
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
|
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
|
||||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||||
F src/os_unix.c 0ca6d8710366fbb01a275160f018334cd347cbda
|
F src/os_unix.c 82986e1e75782b54da7822dca42d36d974fc2948
|
||||||
F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811
|
F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811
|
||||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||||
F src/pager.c 58d2593612acb6b542de6715b4af397ea1fa0a35
|
F src/pager.c 58d2593612acb6b542de6715b4af397ea1fa0a35
|
||||||
F src/pager.h bf25005b4656cd805af43487c3139fca9678d0cc
|
F src/pager.h bf25005b4656cd805af43487c3139fca9678d0cc
|
||||||
F src/parse.y 23737e649c26ce327603799e57f5c2ff50e5e6ba
|
F src/parse.y caad1e98edeca6960493d0c60d31b76820dd7776
|
||||||
F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23
|
F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23
|
||||||
F src/pcache.h 1ff11adce609ba7de139b6abfabaf9a2bac947b5
|
F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
|
||||||
F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051
|
F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051
|
||||||
F src/pragma.c f3e7147299ca05ef4304a36f1fd6e002729c72c6
|
F src/pragma.c f3e7147299ca05ef4304a36f1fd6e002729c72c6
|
||||||
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||||
@ -353,16 +353,16 @@ F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32
|
|||||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||||
F src/resolve.c a83b41104e6ff69855d03cd0aaa09e93927ec39f
|
F src/resolve.c a83b41104e6ff69855d03cd0aaa09e93927ec39f
|
||||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||||
F src/select.c f8fded11fc443a9f5a73cc5db069d06b34460e2f
|
F src/select.c d84c091185bc160c349e8bf460ebd084dbd77e64
|
||||||
F src/shell.c 40ded7e3ade5f2cc89ab1180994f6a6975ebc6f3
|
F src/shell.c 40ded7e3ade5f2cc89ab1180994f6a6975ebc6f3
|
||||||
F src/sqlite.h.in 686be87fcbaea46b1aa8197a17b7a437d39764fc
|
F src/sqlite.h.in 686be87fcbaea46b1aa8197a17b7a437d39764fc
|
||||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||||
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
|
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
|
||||||
F src/sqliteInt.h 961c445154db6d8240ddc0900aa48c5745c23e80
|
F src/sqliteInt.h 09f70fe715a74ea0048ae05526f2a1b6e3a3b6a2
|
||||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
||||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||||
F src/tclsqlite.c e2344bee0d192397f555a24ef3fab26f2ed93bcc
|
F src/tclsqlite.c b2fa693e57720dc87c18183dd5c0399bf7038ebd
|
||||||
F src/test1.c 4f1b42699068b7806af3111786f5ad760c2c1ff7
|
F src/test1.c 4f1b42699068b7806af3111786f5ad760c2c1ff7
|
||||||
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
||||||
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
|
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
|
||||||
@ -420,16 +420,16 @@ F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70
|
|||||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||||
F src/vdbe.c a479a4bd02b6b77b7ff3ff84825fccc0b967fe6a
|
F src/vdbe.c a479a4bd02b6b77b7ff3ff84825fccc0b967fe6a
|
||||||
F src/vdbe.h bfe3f80dba435377cdb64fd917f2529f0f48ab77
|
F src/vdbe.h bfe3f80dba435377cdb64fd917f2529f0f48ab77
|
||||||
F src/vdbeInt.h 4f3b46806b93faa92f0511c7ce30ed31aaec65be
|
F src/vdbeInt.h 1bff4effc71888e3f304e2e6ac7484e39ab78c28
|
||||||
F src/vdbeapi.c ab2cb8fe23fb9f3195f1311eaa800495d83b6118
|
F src/vdbeapi.c ab2cb8fe23fb9f3195f1311eaa800495d83b6118
|
||||||
F src/vdbeaux.c 13ddc450aa8113660497bcbd244139880b30966c
|
F src/vdbeaux.c 77b4a5cbde74f7c3b1d7052c5c4afea89fb20341
|
||||||
F src/vdbeblob.c cc13eca96b8ec51b6248de785a1aec5df11f5805
|
F src/vdbeblob.c cc13eca96b8ec51b6248de785a1aec5df11f5805
|
||||||
F src/vdbemem.c 25b6cfd665b5073480452426e84136edd94140c0
|
F src/vdbemem.c 25b6cfd665b5073480452426e84136edd94140c0
|
||||||
F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d
|
F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d
|
||||||
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
||||||
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
|
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
|
||||||
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||||
F src/wal.c 974928c988681c5157202c79dd9f26afaa7b5086
|
F src/wal.c 92ca9e7923c337c497e4c9aa7edac800e269a1d8
|
||||||
F src/wal.h 907943dfdef10b583e81906679a347e0ec6f1b1b
|
F src/wal.h 907943dfdef10b583e81906679a347e0ec6f1b1b
|
||||||
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
||||||
F src/where.c c6d3d2f6af57d574a7365ee2b225a5024f2a6bec
|
F src/where.c c6d3d2f6af57d574a7365ee2b225a5024f2a6bec
|
||||||
@ -769,7 +769,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
|
|||||||
F test/fuzz3.test 53fabcd5f0f430f8b221282f6c12c4d0903c21eb
|
F test/fuzz3.test 53fabcd5f0f430f8b221282f6c12c4d0903c21eb
|
||||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||||
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
||||||
F test/fuzzcheck.c ccdcdc28579b2c9744696bca8726bdbd729eea11
|
F test/fuzzcheck.c 3309d793165ca61a9996271cb799694839348f9a
|
||||||
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
|
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
|
||||||
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
|
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
|
||||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||||
@ -1082,7 +1082,7 @@ F test/tclsqlite.test 7179b4e0bf236ddf0bfa6bfaefa76fbe0a23c28a
|
|||||||
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
|
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
|
||||||
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||||
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
|
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
|
||||||
F test/tester.tcl 24d971d001a5bb10ef13c27768caed182eb1566e
|
F test/tester.tcl a4b1c8e78ad88426dc0b2375e0b5348d2b841c88
|
||||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||||
@ -1295,12 +1295,12 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
|
|||||||
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
|
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
|
||||||
F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe
|
F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe
|
||||||
F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
|
F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
|
||||||
F test/vtabH.test 492ba03dcb7bb8fedcc53f258c410d04013adbc9
|
F test/vtabH.test 5f5157a1501d9889ec35c1a1832f69612dd31444
|
||||||
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
|
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
|
||||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||||
F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772
|
F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772
|
||||||
F test/wal.test dbfc482e10c7263298833bb1fc60b3ac9d6340a1
|
F test/wal.test 65bfc68f3f09dcbc62cee9f794e560428d96cec7
|
||||||
F test/wal2.test 1f841d2048080d32f552942e333fd99ce541dada
|
F test/wal2.test 1f841d2048080d32f552942e333fd99ce541dada
|
||||||
F test/wal3.test b1d425f68a1f61d12563f0fa1ee6fca7d5afabf4
|
F test/wal3.test b1d425f68a1f61d12563f0fa1ee6fca7d5afabf4
|
||||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||||
@ -1322,6 +1322,7 @@ F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b
|
|||||||
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
|
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
|
||||||
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
|
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
|
||||||
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
|
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
|
||||||
|
F test/waloverwrite.test 8702964967c2f28204f0b4f27af65da81999fc99
|
||||||
F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
|
F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
|
||||||
F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57
|
F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57
|
||||||
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
||||||
@ -1427,7 +1428,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P c785cd7813e4ef6d6f2cb362a0f822713db6bcea fd0a50f0797d154fefff724624f00548b5320566
|
P fa4705c91f9650ecd7ec967dbbf0028aabd8a98c 8e807bfaa197027d0cb73532baa96755ce71ea12
|
||||||
R bf5c420f78514c3466fbe2f1d92a5b04
|
R 207c595909cfacc40e672adb0642fe8a
|
||||||
U drh
|
U drh
|
||||||
Z d51966c7773281c88034ef287a881d30
|
Z c05d49256eed75a98851d063f39abe2d
|
||||||
|
@ -1 +1 @@
|
|||||||
fa4705c91f9650ecd7ec967dbbf0028aabd8a98c
|
c4a858b228a164be2f89f5b01833f0b5e0d7735b
|
@ -169,21 +169,6 @@ int sqlite3BtreeHoldsMutex(Btree *p){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_INCRBLOB
|
|
||||||
/*
|
|
||||||
** Enter and leave a mutex on a Btree given a cursor owned by that
|
|
||||||
** Btree. These entry points are used by incremental I/O and can be
|
|
||||||
** omitted if that module is not used.
|
|
||||||
*/
|
|
||||||
void sqlite3BtreeEnterCursor(BtCursor *pCur){
|
|
||||||
sqlite3BtreeEnter(pCur->pBtree);
|
|
||||||
}
|
|
||||||
void sqlite3BtreeLeaveCursor(BtCursor *pCur){
|
|
||||||
sqlite3BtreeLeave(pCur->pBtree);
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_OMIT_INCRBLOB */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Enter the mutex on every Btree associated with a database
|
** Enter the mutex on every Btree associated with a database
|
||||||
** connection. This is needed (for example) prior to parsing
|
** connection. This is needed (for example) prior to parsing
|
||||||
@ -217,14 +202,6 @@ void sqlite3BtreeLeaveAll(sqlite3 *db){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Return true if a particular Btree requires a lock. Return FALSE if
|
|
||||||
** no lock is ever required since it is not sharable.
|
|
||||||
*/
|
|
||||||
int sqlite3BtreeSharable(Btree *p){
|
|
||||||
return p->sharable;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
/*
|
/*
|
||||||
** Return true if the current thread holds the database connection
|
** Return true if the current thread holds the database connection
|
||||||
@ -298,4 +275,23 @@ void sqlite3BtreeEnterAll(sqlite3 *db){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* if SQLITE_THREADSAFE */
|
#endif /* if SQLITE_THREADSAFE */
|
||||||
|
|
||||||
|
#ifndef SQLITE_OMIT_INCRBLOB
|
||||||
|
/*
|
||||||
|
** Enter a mutex on a Btree given a cursor owned by that Btree.
|
||||||
|
**
|
||||||
|
** These entry points are used by incremental I/O only. Enter() is required
|
||||||
|
** any time OMIT_SHARED_CACHE is not defined, regardless of whether or not
|
||||||
|
** the build is threadsafe. Leave() is only required by threadsafe builds.
|
||||||
|
*/
|
||||||
|
void sqlite3BtreeEnterCursor(BtCursor *pCur){
|
||||||
|
sqlite3BtreeEnter(pCur->pBtree);
|
||||||
|
}
|
||||||
|
# if SQLITE_THREADSAFE
|
||||||
|
void sqlite3BtreeLeaveCursor(BtCursor *pCur){
|
||||||
|
sqlite3BtreeLeave(pCur->pBtree);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#endif /* ifndef SQLITE_OMIT_INCRBLOB */
|
||||||
|
|
||||||
#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */
|
#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */
|
||||||
|
93
src/btree.c
93
src/btree.c
@ -450,6 +450,10 @@ static void releasePage(MemPage *pPage); /* Forward reference */
|
|||||||
static int cursorHoldsMutex(BtCursor *p){
|
static int cursorHoldsMutex(BtCursor *p){
|
||||||
return sqlite3_mutex_held(p->pBt->mutex);
|
return sqlite3_mutex_held(p->pBt->mutex);
|
||||||
}
|
}
|
||||||
|
static int cursorOwnsBtShared(BtCursor *p){
|
||||||
|
assert( cursorHoldsMutex(p) );
|
||||||
|
return (p->pBtree->db==p->pBt->db);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -786,7 +790,7 @@ static int btreeMoveto(
|
|||||||
static int btreeRestoreCursorPosition(BtCursor *pCur){
|
static int btreeRestoreCursorPosition(BtCursor *pCur){
|
||||||
int rc;
|
int rc;
|
||||||
int skipNext;
|
int skipNext;
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pCur->eState>=CURSOR_REQUIRESEEK );
|
assert( pCur->eState>=CURSOR_REQUIRESEEK );
|
||||||
if( pCur->eState==CURSOR_FAULT ){
|
if( pCur->eState==CURSOR_FAULT ){
|
||||||
return pCur->skipNext;
|
return pCur->skipNext;
|
||||||
@ -3126,7 +3130,6 @@ int sqlite3BtreeNewDb(Btree *p){
|
|||||||
** proceed.
|
** proceed.
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
||||||
sqlite3 *pBlock = 0;
|
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
@ -3149,27 +3152,30 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
/* If another database handle has already opened a write transaction
|
{
|
||||||
** on this shared-btree structure and a second write transaction is
|
sqlite3 *pBlock = 0;
|
||||||
** requested, return SQLITE_LOCKED.
|
/* If another database handle has already opened a write transaction
|
||||||
*/
|
** on this shared-btree structure and a second write transaction is
|
||||||
if( (wrflag && pBt->inTransaction==TRANS_WRITE)
|
** requested, return SQLITE_LOCKED.
|
||||||
|| (pBt->btsFlags & BTS_PENDING)!=0
|
*/
|
||||||
){
|
if( (wrflag && pBt->inTransaction==TRANS_WRITE)
|
||||||
pBlock = pBt->pWriter->db;
|
|| (pBt->btsFlags & BTS_PENDING)!=0
|
||||||
}else if( wrflag>1 ){
|
){
|
||||||
BtLock *pIter;
|
pBlock = pBt->pWriter->db;
|
||||||
for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
|
}else if( wrflag>1 ){
|
||||||
if( pIter->pBtree!=p ){
|
BtLock *pIter;
|
||||||
pBlock = pIter->pBtree->db;
|
for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
|
||||||
break;
|
if( pIter->pBtree!=p ){
|
||||||
|
pBlock = pIter->pBtree->db;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if( pBlock ){
|
||||||
if( pBlock ){
|
sqlite3ConnectionBlocked(p->db, pBlock);
|
||||||
sqlite3ConnectionBlocked(p->db, pBlock);
|
rc = SQLITE_LOCKED_SHAREDCACHE;
|
||||||
rc = SQLITE_LOCKED_SHAREDCACHE;
|
goto trans_begun;
|
||||||
goto trans_begun;
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -4286,7 +4292,7 @@ int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
|
|||||||
** to return an integer result code for historical reasons.
|
** to return an integer result code for historical reasons.
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
|
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
assert( pCur->iPage>=0 );
|
assert( pCur->iPage>=0 );
|
||||||
assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
|
assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
|
||||||
@ -4666,7 +4672,7 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
rc = restoreCursorPosition(pCur);
|
rc = restoreCursorPosition(pCur);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
@ -4704,7 +4710,7 @@ static const void *fetchPayload(
|
|||||||
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
|
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
|
||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||||
assert( pCur->info.nSize>0 );
|
assert( pCur->info.nSize>0 );
|
||||||
assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
|
assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
|
||||||
@ -4750,7 +4756,7 @@ const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){
|
|||||||
static int moveToChild(BtCursor *pCur, u32 newPgno){
|
static int moveToChild(BtCursor *pCur, u32 newPgno){
|
||||||
BtShared *pBt = pCur->pBt;
|
BtShared *pBt = pCur->pBt;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
|
assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
|
||||||
assert( pCur->iPage>=0 );
|
assert( pCur->iPage>=0 );
|
||||||
@ -4796,7 +4802,7 @@ static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
|
|||||||
** the largest cell index.
|
** the largest cell index.
|
||||||
*/
|
*/
|
||||||
static void moveToParent(BtCursor *pCur){
|
static void moveToParent(BtCursor *pCur){
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
assert( pCur->iPage>0 );
|
assert( pCur->iPage>0 );
|
||||||
assert( pCur->apPage[pCur->iPage] );
|
assert( pCur->apPage[pCur->iPage] );
|
||||||
@ -4836,7 +4842,7 @@ static int moveToRoot(BtCursor *pCur){
|
|||||||
MemPage *pRoot;
|
MemPage *pRoot;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
|
assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
|
||||||
assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
|
assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
|
||||||
assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
|
assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
|
||||||
@ -4915,7 +4921,7 @@ static int moveToLeftmost(BtCursor *pCur){
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
MemPage *pPage;
|
MemPage *pPage;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
||||||
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
|
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
|
||||||
@ -4940,7 +4946,7 @@ static int moveToRightmost(BtCursor *pCur){
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
MemPage *pPage = 0;
|
MemPage *pPage = 0;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
||||||
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
|
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
|
||||||
@ -4961,7 +4967,7 @@ static int moveToRightmost(BtCursor *pCur){
|
|||||||
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
rc = moveToRoot(pCur);
|
rc = moveToRoot(pCur);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
@ -4984,7 +4990,7 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
|||||||
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
|
|
||||||
/* If the cursor already points to the last entry, this is a no-op. */
|
/* If the cursor already points to the last entry, this is a no-op. */
|
||||||
@ -5062,7 +5068,7 @@ int sqlite3BtreeMovetoUnpacked(
|
|||||||
int rc;
|
int rc;
|
||||||
RecordCompare xRecordCompare;
|
RecordCompare xRecordCompare;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
assert( pRes );
|
assert( pRes );
|
||||||
assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );
|
assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );
|
||||||
@ -5310,7 +5316,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
|
|||||||
int idx;
|
int idx;
|
||||||
MemPage *pPage;
|
MemPage *pPage;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||||
assert( *pRes==0 );
|
assert( *pRes==0 );
|
||||||
if( pCur->eState!=CURSOR_VALID ){
|
if( pCur->eState!=CURSOR_VALID ){
|
||||||
@ -5374,7 +5380,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
|
|||||||
}
|
}
|
||||||
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||||
MemPage *pPage;
|
MemPage *pPage;
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pRes!=0 );
|
assert( pRes!=0 );
|
||||||
assert( *pRes==0 || *pRes==1 );
|
assert( *pRes==0 || *pRes==1 );
|
||||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||||
@ -5419,7 +5425,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
|
|||||||
int rc;
|
int rc;
|
||||||
MemPage *pPage;
|
MemPage *pPage;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pRes!=0 );
|
assert( pRes!=0 );
|
||||||
assert( *pRes==0 );
|
assert( *pRes==0 );
|
||||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||||
@ -5475,7 +5481,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pRes!=0 );
|
assert( pRes!=0 );
|
||||||
assert( *pRes==0 || *pRes==1 );
|
assert( *pRes==0 || *pRes==1 );
|
||||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||||
@ -7955,7 +7961,7 @@ int sqlite3BtreeInsert(
|
|||||||
return pCur->skipNext;
|
return pCur->skipNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( (pCur->curFlags & BTCF_WriteFlag)!=0
|
assert( (pCur->curFlags & BTCF_WriteFlag)!=0
|
||||||
&& pBt->inTransaction==TRANS_WRITE
|
&& pBt->inTransaction==TRANS_WRITE
|
||||||
&& (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
&& (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
||||||
@ -8102,7 +8108,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, int bPreserve){
|
|||||||
u16 szCell; /* Size of the cell being deleted */
|
u16 szCell; /* Size of the cell being deleted */
|
||||||
int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */
|
int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorOwnsBtShared(pCur) );
|
||||||
assert( pBt->inTransaction==TRANS_WRITE );
|
assert( pBt->inTransaction==TRANS_WRITE );
|
||||||
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
||||||
assert( pCur->curFlags & BTCF_WriteFlag );
|
assert( pCur->curFlags & BTCF_WriteFlag );
|
||||||
@ -9564,7 +9570,7 @@ int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
|
|||||||
*/
|
*/
|
||||||
int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
||||||
int rc;
|
int rc;
|
||||||
assert( cursorHoldsMutex(pCsr) );
|
assert( cursorOwnsBtShared(pCsr) );
|
||||||
assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
|
assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
|
||||||
assert( pCsr->curFlags & BTCF_Incrblob );
|
assert( pCsr->curFlags & BTCF_Incrblob );
|
||||||
|
|
||||||
@ -9671,3 +9677,12 @@ int sqlite3BtreeIsReadonly(Btree *p){
|
|||||||
** Return the size of the header added to each page by this module.
|
** Return the size of the header added to each page by this module.
|
||||||
*/
|
*/
|
||||||
int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
|
int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
|
||||||
|
|
||||||
|
#if !defined(SQLITE_OMIT_SHARED_CACHE)
|
||||||
|
/*
|
||||||
|
** Return true if the Btree passed as the only argument is sharable.
|
||||||
|
*/
|
||||||
|
int sqlite3BtreeSharable(Btree *p){
|
||||||
|
return p->sharable;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -287,15 +287,17 @@ void sqlite3BtreeCursorList(Btree*);
|
|||||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
void sqlite3BtreeEnter(Btree*);
|
void sqlite3BtreeEnter(Btree*);
|
||||||
void sqlite3BtreeEnterAll(sqlite3*);
|
void sqlite3BtreeEnterAll(sqlite3*);
|
||||||
|
int sqlite3BtreeSharable(Btree*);
|
||||||
|
void sqlite3BtreeEnterCursor(BtCursor*);
|
||||||
#else
|
#else
|
||||||
# define sqlite3BtreeEnter(X)
|
# define sqlite3BtreeEnter(X)
|
||||||
# define sqlite3BtreeEnterAll(X)
|
# define sqlite3BtreeEnterAll(X)
|
||||||
|
# define sqlite3BtreeSharable(X) 0
|
||||||
|
# define sqlite3BtreeEnterCursor(X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
|
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
|
||||||
int sqlite3BtreeSharable(Btree*);
|
|
||||||
void sqlite3BtreeLeave(Btree*);
|
void sqlite3BtreeLeave(Btree*);
|
||||||
void sqlite3BtreeEnterCursor(BtCursor*);
|
|
||||||
void sqlite3BtreeLeaveCursor(BtCursor*);
|
void sqlite3BtreeLeaveCursor(BtCursor*);
|
||||||
void sqlite3BtreeLeaveAll(sqlite3*);
|
void sqlite3BtreeLeaveAll(sqlite3*);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -306,9 +308,7 @@ void sqlite3BtreeCursorList(Btree*);
|
|||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
|
||||||
# define sqlite3BtreeSharable(X) 0
|
|
||||||
# define sqlite3BtreeLeave(X)
|
# define sqlite3BtreeLeave(X)
|
||||||
# define sqlite3BtreeEnterCursor(X)
|
|
||||||
# define sqlite3BtreeLeaveCursor(X)
|
# define sqlite3BtreeLeaveCursor(X)
|
||||||
# define sqlite3BtreeLeaveAll(X)
|
# define sqlite3BtreeLeaveAll(X)
|
||||||
|
|
||||||
|
@ -24,15 +24,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
/*
|
|
||||||
** This routine is called when a new SQL statement is beginning to
|
|
||||||
** be parsed. Initialize the pParse structure as needed.
|
|
||||||
*/
|
|
||||||
void sqlite3BeginParse(Parse *pParse, int explainFlag){
|
|
||||||
pParse->explain = (u8)explainFlag;
|
|
||||||
pParse->nVar = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
/*
|
/*
|
||||||
** The TableLock structure is only used by the sqlite3TableLock() and
|
** The TableLock structure is only used by the sqlite3TableLock() and
|
||||||
|
@ -461,8 +461,9 @@ Expr *sqlite3ExprAlloc(
|
|||||||
assert( iValue>=0 );
|
assert( iValue>=0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra);
|
pNew = sqlite3DbMallocRaw(db, sizeof(Expr)+nExtra);
|
||||||
if( pNew ){
|
if( pNew ){
|
||||||
|
memset(pNew, 0, sizeof(Expr));
|
||||||
pNew->op = (u8)op;
|
pNew->op = (u8)op;
|
||||||
pNew->iAgg = -1;
|
pNew->iAgg = -1;
|
||||||
if( pToken ){
|
if( pToken ){
|
||||||
|
37
src/func.c
37
src/func.c
@ -567,10 +567,10 @@ static void total_changes(
|
|||||||
** A structure defining how to do GLOB-style comparisons.
|
** A structure defining how to do GLOB-style comparisons.
|
||||||
*/
|
*/
|
||||||
struct compareInfo {
|
struct compareInfo {
|
||||||
u8 matchAll;
|
u8 matchAll; /* "*" or "%" */
|
||||||
u8 matchOne;
|
u8 matchOne; /* "?" or "_" */
|
||||||
u8 matchSet;
|
u8 matchSet; /* "[" or 0 */
|
||||||
u8 noCase;
|
u8 noCase; /* true to ignore case differences */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -633,22 +633,14 @@ static int patternCompare(
|
|||||||
const u8 *zPattern, /* The glob pattern */
|
const u8 *zPattern, /* The glob pattern */
|
||||||
const u8 *zString, /* The string to compare against the glob */
|
const u8 *zString, /* The string to compare against the glob */
|
||||||
const struct compareInfo *pInfo, /* Information about how to do the compare */
|
const struct compareInfo *pInfo, /* Information about how to do the compare */
|
||||||
u32 esc /* The escape character */
|
u32 matchOther /* The escape char (LIKE) or '[' (GLOB) */
|
||||||
){
|
){
|
||||||
u32 c, c2; /* Next pattern and input string chars */
|
u32 c, c2; /* Next pattern and input string chars */
|
||||||
u32 matchOne = pInfo->matchOne; /* "?" or "_" */
|
u32 matchOne = pInfo->matchOne; /* "?" or "_" */
|
||||||
u32 matchAll = pInfo->matchAll; /* "*" or "%" */
|
u32 matchAll = pInfo->matchAll; /* "*" or "%" */
|
||||||
u32 matchOther; /* "[" or the escape character */
|
|
||||||
u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */
|
u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */
|
||||||
const u8 *zEscaped = 0; /* One past the last escaped input char */
|
const u8 *zEscaped = 0; /* One past the last escaped input char */
|
||||||
|
|
||||||
/* The GLOB operator does not have an ESCAPE clause. And LIKE does not
|
|
||||||
** have the matchSet operator. So we either have to look for one or
|
|
||||||
** the other, never both. Hence the single variable matchOther is used
|
|
||||||
** to store the one we have to look for.
|
|
||||||
*/
|
|
||||||
matchOther = esc ? esc : pInfo->matchSet;
|
|
||||||
|
|
||||||
while( (c = Utf8Read(zPattern))!=0 ){
|
while( (c = Utf8Read(zPattern))!=0 ){
|
||||||
if( c==matchAll ){ /* Match "*" */
|
if( c==matchAll ){ /* Match "*" */
|
||||||
/* Skip over multiple "*" characters in the pattern. If there
|
/* Skip over multiple "*" characters in the pattern. If there
|
||||||
@ -662,7 +654,7 @@ static int patternCompare(
|
|||||||
if( c==0 ){
|
if( c==0 ){
|
||||||
return 1; /* "*" at the end of the pattern matches */
|
return 1; /* "*" at the end of the pattern matches */
|
||||||
}else if( c==matchOther ){
|
}else if( c==matchOther ){
|
||||||
if( esc ){
|
if( pInfo->matchSet==0 ){
|
||||||
c = sqlite3Utf8Read(&zPattern);
|
c = sqlite3Utf8Read(&zPattern);
|
||||||
if( c==0 ) return 0;
|
if( c==0 ) return 0;
|
||||||
}else{
|
}else{
|
||||||
@ -670,7 +662,7 @@ static int patternCompare(
|
|||||||
** recursive search in this case, but it is an unusual case. */
|
** recursive search in this case, but it is an unusual case. */
|
||||||
assert( matchOther<0x80 ); /* '[' is a single-byte character */
|
assert( matchOther<0x80 ); /* '[' is a single-byte character */
|
||||||
while( *zString
|
while( *zString
|
||||||
&& patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
|
&& patternCompare(&zPattern[-1],zString,pInfo,matchOther)==0 ){
|
||||||
SQLITE_SKIP_UTF8(zString);
|
SQLITE_SKIP_UTF8(zString);
|
||||||
}
|
}
|
||||||
return *zString!=0;
|
return *zString!=0;
|
||||||
@ -696,18 +688,18 @@ static int patternCompare(
|
|||||||
}
|
}
|
||||||
while( (c2 = *(zString++))!=0 ){
|
while( (c2 = *(zString++))!=0 ){
|
||||||
if( c2!=c && c2!=cx ) continue;
|
if( c2!=c && c2!=cx ) continue;
|
||||||
if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
|
if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
while( (c2 = Utf8Read(zString))!=0 ){
|
while( (c2 = Utf8Read(zString))!=0 ){
|
||||||
if( c2!=c ) continue;
|
if( c2!=c ) continue;
|
||||||
if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
|
if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if( c==matchOther ){
|
if( c==matchOther ){
|
||||||
if( esc ){
|
if( pInfo->matchSet==0 ){
|
||||||
c = sqlite3Utf8Read(&zPattern);
|
c = sqlite3Utf8Read(&zPattern);
|
||||||
if( c==0 ) return 0;
|
if( c==0 ) return 0;
|
||||||
zEscaped = zPattern;
|
zEscaped = zPattern;
|
||||||
@ -760,7 +752,7 @@ static int patternCompare(
|
|||||||
** The sqlite3_strglob() interface.
|
** The sqlite3_strglob() interface.
|
||||||
*/
|
*/
|
||||||
int sqlite3_strglob(const char *zGlobPattern, const char *zString){
|
int sqlite3_strglob(const char *zGlobPattern, const char *zString){
|
||||||
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
|
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[')==0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -798,9 +790,10 @@ static void likeFunc(
|
|||||||
sqlite3_value **argv
|
sqlite3_value **argv
|
||||||
){
|
){
|
||||||
const unsigned char *zA, *zB;
|
const unsigned char *zA, *zB;
|
||||||
u32 escape = 0;
|
u32 escape;
|
||||||
int nPat;
|
int nPat;
|
||||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||||
|
struct compareInfo *pInfo = sqlite3_user_data(context);
|
||||||
|
|
||||||
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||||
if( sqlite3_value_type(argv[0])==SQLITE_BLOB
|
if( sqlite3_value_type(argv[0])==SQLITE_BLOB
|
||||||
@ -840,13 +833,13 @@ static void likeFunc(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
escape = sqlite3Utf8Read(&zEsc);
|
escape = sqlite3Utf8Read(&zEsc);
|
||||||
|
}else{
|
||||||
|
escape = pInfo->matchSet;
|
||||||
}
|
}
|
||||||
if( zA && zB ){
|
if( zA && zB ){
|
||||||
struct compareInfo *pInfo = sqlite3_user_data(context);
|
|
||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
sqlite3_like_count++;
|
sqlite3_like_count++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
|
sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
src/mem5.c
16
src/mem5.c
@ -102,6 +102,7 @@ static SQLITE_WSD struct Mem5Global {
|
|||||||
*/
|
*/
|
||||||
sqlite3_mutex *mutex;
|
sqlite3_mutex *mutex;
|
||||||
|
|
||||||
|
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||||
/*
|
/*
|
||||||
** Performance statistics
|
** Performance statistics
|
||||||
*/
|
*/
|
||||||
@ -113,6 +114,7 @@ static SQLITE_WSD struct Mem5Global {
|
|||||||
u32 maxOut; /* Maximum instantaneous currentOut */
|
u32 maxOut; /* Maximum instantaneous currentOut */
|
||||||
u32 maxCount; /* Maximum instantaneous currentCount */
|
u32 maxCount; /* Maximum instantaneous currentCount */
|
||||||
u32 maxRequest; /* Largest allocation (exclusive of internal frag) */
|
u32 maxRequest; /* Largest allocation (exclusive of internal frag) */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Lists of free blocks. aiFreelist[0] is a list of free blocks of
|
** Lists of free blocks. aiFreelist[0] is a list of free blocks of
|
||||||
@ -224,14 +226,17 @@ static void *memsys5MallocUnsafe(int nByte){
|
|||||||
/* nByte must be a positive */
|
/* nByte must be a positive */
|
||||||
assert( nByte>0 );
|
assert( nByte>0 );
|
||||||
|
|
||||||
|
/* No more than 1GiB per allocation */
|
||||||
|
if( nByte > 0x40000000 ) return 0;
|
||||||
|
|
||||||
|
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||||
/* Keep track of the maximum allocation request. Even unfulfilled
|
/* Keep track of the maximum allocation request. Even unfulfilled
|
||||||
** requests are counted */
|
** requests are counted */
|
||||||
if( (u32)nByte>mem5.maxRequest ){
|
if( (u32)nByte>mem5.maxRequest ){
|
||||||
/* Abort if the requested allocation size is larger than the largest
|
|
||||||
** power of two that we can represent using 32-bit signed integers. */
|
|
||||||
if( nByte > 0x40000000 ) return 0;
|
|
||||||
mem5.maxRequest = nByte;
|
mem5.maxRequest = nByte;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Round nByte up to the next valid power of two */
|
/* Round nByte up to the next valid power of two */
|
||||||
for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte; iFullSz*=2,iLogsize++){}
|
for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte; iFullSz*=2,iLogsize++){}
|
||||||
@ -258,6 +263,7 @@ static void *memsys5MallocUnsafe(int nByte){
|
|||||||
}
|
}
|
||||||
mem5.aCtrl[i] = iLogsize;
|
mem5.aCtrl[i] = iLogsize;
|
||||||
|
|
||||||
|
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||||
/* Update allocator performance statistics. */
|
/* Update allocator performance statistics. */
|
||||||
mem5.nAlloc++;
|
mem5.nAlloc++;
|
||||||
mem5.totalAlloc += iFullSz;
|
mem5.totalAlloc += iFullSz;
|
||||||
@ -266,6 +272,7 @@ static void *memsys5MallocUnsafe(int nByte){
|
|||||||
mem5.currentOut += iFullSz;
|
mem5.currentOut += iFullSz;
|
||||||
if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
|
if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
|
||||||
if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
|
if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
/* Make sure the allocated memory does not assume that it is set to zero
|
/* Make sure the allocated memory does not assume that it is set to zero
|
||||||
@ -300,12 +307,15 @@ static void memsys5FreeUnsafe(void *pOld){
|
|||||||
|
|
||||||
mem5.aCtrl[iBlock] |= CTRL_FREE;
|
mem5.aCtrl[iBlock] |= CTRL_FREE;
|
||||||
mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
|
mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
|
||||||
|
|
||||||
|
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||||
assert( mem5.currentCount>0 );
|
assert( mem5.currentCount>0 );
|
||||||
assert( mem5.currentOut>=(size*mem5.szAtom) );
|
assert( mem5.currentOut>=(size*mem5.szAtom) );
|
||||||
mem5.currentCount--;
|
mem5.currentCount--;
|
||||||
mem5.currentOut -= size*mem5.szAtom;
|
mem5.currentOut -= size*mem5.szAtom;
|
||||||
assert( mem5.currentOut>0 || mem5.currentCount==0 );
|
assert( mem5.currentOut>0 || mem5.currentCount==0 );
|
||||||
assert( mem5.currentCount>0 || mem5.currentOut==0 );
|
assert( mem5.currentCount>0 || mem5.currentOut==0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
|
mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
|
||||||
while( ALWAYS(iLogsize<LOGMAX) ){
|
while( ALWAYS(iLogsize<LOGMAX) ){
|
||||||
|
@ -437,26 +437,36 @@ static struct unix_syscall {
|
|||||||
#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
|
#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
|
||||||
|
|
||||||
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
|
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
|
||||||
{ "mmap", (sqlite3_syscall_ptr)mmap, 0 },
|
{ "mmap", (sqlite3_syscall_ptr)mmap, 0 },
|
||||||
|
#else
|
||||||
|
{ "mmap", (sqlite3_syscall_ptr)0, 0 },
|
||||||
|
#endif
|
||||||
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)
|
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)
|
||||||
|
|
||||||
|
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
|
||||||
{ "munmap", (sqlite3_syscall_ptr)munmap, 0 },
|
{ "munmap", (sqlite3_syscall_ptr)munmap, 0 },
|
||||||
|
#else
|
||||||
|
{ "munmap", (sqlite3_syscall_ptr)0, 0 },
|
||||||
|
#endif
|
||||||
#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
|
#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
|
||||||
|
|
||||||
#if HAVE_MREMAP
|
#if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
|
||||||
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
|
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
|
||||||
#else
|
#else
|
||||||
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
|
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
|
||||||
#endif
|
#endif
|
||||||
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent)
|
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent)
|
||||||
|
|
||||||
|
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
|
||||||
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
|
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
|
||||||
|
#else
|
||||||
|
{ "getpagesize", (sqlite3_syscall_ptr)0, 0 },
|
||||||
|
#endif
|
||||||
#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent)
|
#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent)
|
||||||
|
|
||||||
{ "readlink", (sqlite3_syscall_ptr)readlink, 0 },
|
{ "readlink", (sqlite3_syscall_ptr)readlink, 0 },
|
||||||
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
|
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}; /* End of the overrideable system calls */
|
}; /* End of the overrideable system calls */
|
||||||
|
|
||||||
|
@ -114,10 +114,10 @@ cmdlist ::= cmdlist ecmd.
|
|||||||
cmdlist ::= ecmd.
|
cmdlist ::= ecmd.
|
||||||
ecmd ::= SEMI.
|
ecmd ::= SEMI.
|
||||||
ecmd ::= explain cmdx SEMI.
|
ecmd ::= explain cmdx SEMI.
|
||||||
explain ::= . { sqlite3BeginParse(pParse, 0); }
|
explain ::= .
|
||||||
%ifndef SQLITE_OMIT_EXPLAIN
|
%ifndef SQLITE_OMIT_EXPLAIN
|
||||||
explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); }
|
explain ::= EXPLAIN. { pParse->explain = 1; }
|
||||||
explain ::= EXPLAIN QUERY PLAN. { sqlite3BeginParse(pParse, 2); }
|
explain ::= EXPLAIN QUERY PLAN. { pParse->explain = 2; }
|
||||||
%endif SQLITE_OMIT_EXPLAIN
|
%endif SQLITE_OMIT_EXPLAIN
|
||||||
cmdx ::= cmd. { sqlite3FinishCoding(pParse); }
|
cmdx ::= cmd. { sqlite3FinishCoding(pParse); }
|
||||||
|
|
||||||
|
@ -55,6 +55,8 @@ struct PgHdr {
|
|||||||
#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */
|
#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */
|
||||||
#define PGHDR_MMAP 0x040 /* This is an mmap page object */
|
#define PGHDR_MMAP 0x040 /* This is an mmap page object */
|
||||||
|
|
||||||
|
#define PGHDR_WAL_APPEND 0x080 /* Appended to wal file */
|
||||||
|
|
||||||
/* Initialize and shutdown the page cache subsystem */
|
/* Initialize and shutdown the page cache subsystem */
|
||||||
int sqlite3PcacheInitialize(void);
|
int sqlite3PcacheInitialize(void);
|
||||||
void sqlite3PcacheShutdown(void);
|
void sqlite3PcacheShutdown(void);
|
||||||
|
17
src/select.c
17
src/select.c
@ -111,29 +111,34 @@ Select *sqlite3SelectNew(
|
|||||||
Select *pNew;
|
Select *pNew;
|
||||||
Select standin;
|
Select standin;
|
||||||
sqlite3 *db = pParse->db;
|
sqlite3 *db = pParse->db;
|
||||||
pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
|
pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
|
||||||
if( pNew==0 ){
|
if( pNew==0 ){
|
||||||
assert( db->mallocFailed );
|
assert( db->mallocFailed );
|
||||||
pNew = &standin;
|
pNew = &standin;
|
||||||
memset(pNew, 0, sizeof(*pNew));
|
|
||||||
}
|
}
|
||||||
if( pEList==0 ){
|
if( pEList==0 ){
|
||||||
pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
|
pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
|
||||||
}
|
}
|
||||||
pNew->pEList = pEList;
|
pNew->pEList = pEList;
|
||||||
|
pNew->op = TK_SELECT;
|
||||||
|
pNew->selFlags = selFlags;
|
||||||
|
pNew->iLimit = 0;
|
||||||
|
pNew->iOffset = 0;
|
||||||
|
pNew->addrOpenEphm[0] = -1;
|
||||||
|
pNew->addrOpenEphm[1] = -1;
|
||||||
|
pNew->nSelectRow = 0;
|
||||||
if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
|
if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
|
||||||
pNew->pSrc = pSrc;
|
pNew->pSrc = pSrc;
|
||||||
pNew->pWhere = pWhere;
|
pNew->pWhere = pWhere;
|
||||||
pNew->pGroupBy = pGroupBy;
|
pNew->pGroupBy = pGroupBy;
|
||||||
pNew->pHaving = pHaving;
|
pNew->pHaving = pHaving;
|
||||||
pNew->pOrderBy = pOrderBy;
|
pNew->pOrderBy = pOrderBy;
|
||||||
pNew->selFlags = selFlags;
|
pNew->pPrior = 0;
|
||||||
pNew->op = TK_SELECT;
|
pNew->pNext = 0;
|
||||||
pNew->pLimit = pLimit;
|
pNew->pLimit = pLimit;
|
||||||
pNew->pOffset = pOffset;
|
pNew->pOffset = pOffset;
|
||||||
|
pNew->pWith = 0;
|
||||||
assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
|
assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
|
||||||
pNew->addrOpenEphm[0] = -1;
|
|
||||||
pNew->addrOpenEphm[1] = -1;
|
|
||||||
if( db->mallocFailed ) {
|
if( db->mallocFailed ) {
|
||||||
clearSelect(db, pNew, pNew!=&standin);
|
clearSelect(db, pNew, pNew!=&standin);
|
||||||
pNew = 0;
|
pNew = 0;
|
||||||
|
@ -767,10 +767,6 @@ typedef INT16_TYPE LogEst;
|
|||||||
*/
|
*/
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# include <TargetConditionals.h>
|
# include <TargetConditionals.h>
|
||||||
# if TARGET_OS_IPHONE
|
|
||||||
# undef SQLITE_MAX_MMAP_SIZE
|
|
||||||
# define SQLITE_MAX_MMAP_SIZE 0
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef SQLITE_MAX_MMAP_SIZE
|
#ifndef SQLITE_MAX_MMAP_SIZE
|
||||||
# if defined(__linux__) \
|
# if defined(__linux__) \
|
||||||
@ -3352,7 +3348,6 @@ void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
|
|||||||
void sqlite3ResetAllSchemasOfConnection(sqlite3*);
|
void sqlite3ResetAllSchemasOfConnection(sqlite3*);
|
||||||
void sqlite3ResetOneSchema(sqlite3*,int);
|
void sqlite3ResetOneSchema(sqlite3*,int);
|
||||||
void sqlite3CollapseDatabaseArray(sqlite3*);
|
void sqlite3CollapseDatabaseArray(sqlite3*);
|
||||||
void sqlite3BeginParse(Parse*,int);
|
|
||||||
void sqlite3CommitInternalChanges(sqlite3*);
|
void sqlite3CommitInternalChanges(sqlite3*);
|
||||||
void sqlite3DeleteColumnNames(sqlite3*,Table*);
|
void sqlite3DeleteColumnNames(sqlite3*,Table*);
|
||||||
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
|
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
|
||||||
|
@ -3122,6 +3122,10 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
|
Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
if( strcmp(zArg,"-sourceid")==0 ){
|
||||||
|
Tcl_AppendResult(interp,sqlite3_sourceid(), (char*)0);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
if( strcmp(zArg,"-has-codec")==0 ){
|
if( strcmp(zArg,"-has-codec")==0 ){
|
||||||
#ifdef SQLITE_HAS_CODEC
|
#ifdef SQLITE_HAS_CODEC
|
||||||
Tcl_AppendResult(interp,"1",(char*)0);
|
Tcl_AppendResult(interp,"1",(char*)0);
|
||||||
|
@ -510,11 +510,15 @@ int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
|
|||||||
int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
|
int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
|
||||||
int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
|
int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
|
||||||
|
|
||||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
|
#if !defined(SQLITE_OMIT_SHARED_CACHE)
|
||||||
void sqlite3VdbeEnter(Vdbe*);
|
void sqlite3VdbeEnter(Vdbe*);
|
||||||
void sqlite3VdbeLeave(Vdbe*);
|
|
||||||
#else
|
#else
|
||||||
# define sqlite3VdbeEnter(X)
|
# define sqlite3VdbeEnter(X)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
|
||||||
|
void sqlite3VdbeLeave(Vdbe*);
|
||||||
|
#else
|
||||||
# define sqlite3VdbeLeave(X)
|
# define sqlite3VdbeLeave(X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1318,7 +1318,7 @@ void sqlite3VdbeUsesBtree(Vdbe *p, int i){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
|
#if !defined(SQLITE_OMIT_SHARED_CACHE)
|
||||||
/*
|
/*
|
||||||
** If SQLite is compiled to support shared-cache mode and to be threadsafe,
|
** If SQLite is compiled to support shared-cache mode and to be threadsafe,
|
||||||
** this routine obtains the mutex associated with each BtShared structure
|
** this routine obtains the mutex associated with each BtShared structure
|
||||||
|
107
src/wal.c
107
src/wal.c
@ -445,6 +445,7 @@ struct Wal {
|
|||||||
u8 padToSectorBoundary; /* Pad transactions out to the next sector */
|
u8 padToSectorBoundary; /* Pad transactions out to the next sector */
|
||||||
WalIndexHdr hdr; /* Wal-index header for current transaction */
|
WalIndexHdr hdr; /* Wal-index header for current transaction */
|
||||||
u32 minFrame; /* Ignore wal frames before this one */
|
u32 minFrame; /* Ignore wal frames before this one */
|
||||||
|
u32 iReCksum; /* On commit, recalculate checksums from here */
|
||||||
const char *zWalName; /* Name of WAL file */
|
const char *zWalName; /* Name of WAL file */
|
||||||
u32 nCkpt; /* Checkpoint sequence counter in the wal-header */
|
u32 nCkpt; /* Checkpoint sequence counter in the wal-header */
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
@ -698,14 +699,16 @@ static void walEncodeFrame(
|
|||||||
assert( WAL_FRAME_HDRSIZE==24 );
|
assert( WAL_FRAME_HDRSIZE==24 );
|
||||||
sqlite3Put4byte(&aFrame[0], iPage);
|
sqlite3Put4byte(&aFrame[0], iPage);
|
||||||
sqlite3Put4byte(&aFrame[4], nTruncate);
|
sqlite3Put4byte(&aFrame[4], nTruncate);
|
||||||
memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
|
if( pWal->iReCksum==0 ){
|
||||||
|
memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
|
||||||
|
|
||||||
nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
|
nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
|
||||||
walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
|
walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
|
||||||
walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
|
walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
|
||||||
|
|
||||||
sqlite3Put4byte(&aFrame[16], aCksum[0]);
|
sqlite3Put4byte(&aFrame[16], aCksum[0]);
|
||||||
sqlite3Put4byte(&aFrame[20], aCksum[1]);
|
sqlite3Put4byte(&aFrame[20], aCksum[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2632,6 +2635,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
|
|||||||
/* Cannot start a write transaction without first holding a read
|
/* Cannot start a write transaction without first holding a read
|
||||||
** transaction. */
|
** transaction. */
|
||||||
assert( pWal->readLock>=0 );
|
assert( pWal->readLock>=0 );
|
||||||
|
assert( pWal->writeLock==0 && pWal->iReCksum==0 );
|
||||||
|
|
||||||
if( pWal->readOnly ){
|
if( pWal->readOnly ){
|
||||||
return SQLITE_READONLY;
|
return SQLITE_READONLY;
|
||||||
@ -2667,6 +2671,7 @@ int sqlite3WalEndWriteTransaction(Wal *pWal){
|
|||||||
if( pWal->writeLock ){
|
if( pWal->writeLock ){
|
||||||
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
||||||
pWal->writeLock = 0;
|
pWal->writeLock = 0;
|
||||||
|
pWal->iReCksum = 0;
|
||||||
pWal->truncateOnCommit = 0;
|
pWal->truncateOnCommit = 0;
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@ -2885,6 +2890,59 @@ static int walWriteOneFrame(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This function is called as part of committing a transaction within which
|
||||||
|
** one or more frames have been overwritten. It updates the checksums for
|
||||||
|
** all frames written to the wal file by the current transaction starting
|
||||||
|
** with the earliest to have been overwritten.
|
||||||
|
**
|
||||||
|
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
|
||||||
|
*/
|
||||||
|
static int walRewriteChecksums(Wal *pWal, u32 iLast){
|
||||||
|
const int szPage = pWal->szPage;/* Database page size */
|
||||||
|
int rc = SQLITE_OK; /* Return code */
|
||||||
|
u8 *aBuf; /* Buffer to load data from wal file into */
|
||||||
|
u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-headers in */
|
||||||
|
u32 iRead; /* Next frame to read from wal file */
|
||||||
|
i64 iCksumOff;
|
||||||
|
|
||||||
|
aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
|
||||||
|
if( aBuf==0 ) return SQLITE_NOMEM;
|
||||||
|
|
||||||
|
/* Find the checksum values to use as input for the recalculating the
|
||||||
|
** first checksum. If the first frame is frame 1 (implying that the current
|
||||||
|
** transaction restarted the wal file), these values must be read from the
|
||||||
|
** wal-file header. Otherwise, read them from the frame header of the
|
||||||
|
** previous frame. */
|
||||||
|
assert( pWal->iReCksum>0 );
|
||||||
|
if( pWal->iReCksum==1 ){
|
||||||
|
iCksumOff = 24;
|
||||||
|
}else{
|
||||||
|
iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16;
|
||||||
|
}
|
||||||
|
rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff);
|
||||||
|
pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf);
|
||||||
|
pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]);
|
||||||
|
|
||||||
|
iRead = pWal->iReCksum;
|
||||||
|
pWal->iReCksum = 0;
|
||||||
|
for(; rc==SQLITE_OK && iRead<=iLast; iRead++){
|
||||||
|
i64 iOff = walFrameOffset(iRead, szPage);
|
||||||
|
rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
u32 iPgno, nDbSize;
|
||||||
|
iPgno = sqlite3Get4byte(aBuf);
|
||||||
|
nDbSize = sqlite3Get4byte(&aBuf[4]);
|
||||||
|
|
||||||
|
walEncodeFrame(pWal, iPgno, nDbSize, &aBuf[WAL_FRAME_HDRSIZE], aFrame);
|
||||||
|
rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_free(aBuf);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Write a set of frames to the log. The caller must hold the write-lock
|
** Write a set of frames to the log. The caller must hold the write-lock
|
||||||
** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
|
** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
|
||||||
@ -2905,6 +2963,8 @@ int sqlite3WalFrames(
|
|||||||
int szFrame; /* The size of a single frame */
|
int szFrame; /* The size of a single frame */
|
||||||
i64 iOffset; /* Next byte to write in WAL file */
|
i64 iOffset; /* Next byte to write in WAL file */
|
||||||
WalWriter w; /* The writer */
|
WalWriter w; /* The writer */
|
||||||
|
u32 iFirst = 0; /* First frame that may be overwritten */
|
||||||
|
WalIndexHdr *pLive; /* Pointer to shared header */
|
||||||
|
|
||||||
assert( pList );
|
assert( pList );
|
||||||
assert( pWal->writeLock );
|
assert( pWal->writeLock );
|
||||||
@ -2920,6 +2980,11 @@ int sqlite3WalFrames(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pLive = (WalIndexHdr*)walIndexHdr(pWal);
|
||||||
|
if( memcmp(&pWal->hdr, (void *)pLive, sizeof(WalIndexHdr))!=0 ){
|
||||||
|
iFirst = pLive->mxFrame+1;
|
||||||
|
}
|
||||||
|
|
||||||
/* See if it is possible to write these frames into the start of the
|
/* See if it is possible to write these frames into the start of the
|
||||||
** log file, instead of appending to it at pWal->hdr.mxFrame.
|
** log file, instead of appending to it at pWal->hdr.mxFrame.
|
||||||
*/
|
*/
|
||||||
@ -2984,6 +3049,27 @@ int sqlite3WalFrames(
|
|||||||
/* Write all frames into the log file exactly once */
|
/* Write all frames into the log file exactly once */
|
||||||
for(p=pList; p; p=p->pDirty){
|
for(p=pList; p; p=p->pDirty){
|
||||||
int nDbSize; /* 0 normally. Positive == commit flag */
|
int nDbSize; /* 0 normally. Positive == commit flag */
|
||||||
|
|
||||||
|
/* Check if this page has already been written into the wal file by
|
||||||
|
** the current transaction. If so, overwrite the existing frame and
|
||||||
|
** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that
|
||||||
|
** checksums must be recomputed when the transaction is committed. */
|
||||||
|
if( iFirst && (p->pDirty || isCommit==0) ){
|
||||||
|
u32 iWrite = 0;
|
||||||
|
VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite);
|
||||||
|
assert( rc==SQLITE_OK || iWrite==0 );
|
||||||
|
if( iWrite>=iFirst ){
|
||||||
|
i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE;
|
||||||
|
if( pWal->iReCksum==0 || iWrite<pWal->iReCksum ){
|
||||||
|
pWal->iReCksum = iWrite;
|
||||||
|
}
|
||||||
|
rc = sqlite3OsWrite(pWal->pWalFd, p->pData, szPage, iOff);
|
||||||
|
if( rc ) return rc;
|
||||||
|
p->flags &= ~PGHDR_WAL_APPEND;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iFrame++;
|
iFrame++;
|
||||||
assert( iOffset==walFrameOffset(iFrame, szPage) );
|
assert( iOffset==walFrameOffset(iFrame, szPage) );
|
||||||
nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
|
nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
|
||||||
@ -2991,6 +3077,13 @@ int sqlite3WalFrames(
|
|||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
pLast = p;
|
pLast = p;
|
||||||
iOffset += szFrame;
|
iOffset += szFrame;
|
||||||
|
p->flags |= PGHDR_WAL_APPEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recalculate checksums within the wal file if required. */
|
||||||
|
if( isCommit && pWal->iReCksum ){
|
||||||
|
rc = walRewriteChecksums(pWal, iFrame);
|
||||||
|
if( rc ) return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is the end of a transaction, then we might need to pad
|
/* If this is the end of a transaction, then we might need to pad
|
||||||
@ -3042,6 +3135,7 @@ int sqlite3WalFrames(
|
|||||||
*/
|
*/
|
||||||
iFrame = pWal->hdr.mxFrame;
|
iFrame = pWal->hdr.mxFrame;
|
||||||
for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
|
for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
|
||||||
|
if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue;
|
||||||
iFrame++;
|
iFrame++;
|
||||||
rc = walIndexAppend(pWal, iFrame, p->pgno);
|
rc = walIndexAppend(pWal, iFrame, p->pgno);
|
||||||
}
|
}
|
||||||
@ -3154,6 +3248,7 @@ int sqlite3WalCheckpoint(
|
|||||||
|
|
||||||
/* Copy data from the log to the database file. */
|
/* Copy data from the log to the database file. */
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
|
|
||||||
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
|
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
|
||||||
rc = SQLITE_CORRUPT_BKPT;
|
rc = SQLITE_CORRUPT_BKPT;
|
||||||
}else{
|
}else{
|
||||||
|
@ -865,8 +865,13 @@ int main(int argc, char **argv){
|
|||||||
return 0;
|
return 0;
|
||||||
}else
|
}else
|
||||||
if( strcmp(z,"limit-mem")==0 ){
|
if( strcmp(z,"limit-mem")==0 ){
|
||||||
|
#if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5)
|
||||||
|
fatalError("the %s option requires -DSQLITE_ENABLE_MEMSYS5 or _MEMSYS3",
|
||||||
|
argv[i]);
|
||||||
|
#else
|
||||||
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
|
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
|
||||||
nMem = integerValue(argv[++i]);
|
nMem = integerValue(argv[++i]);
|
||||||
|
#endif
|
||||||
}else
|
}else
|
||||||
if( strcmp(z,"limit-vdbe")==0 ){
|
if( strcmp(z,"limit-vdbe")==0 ){
|
||||||
vdbeLimitFlag = 1;
|
vdbeLimitFlag = 1;
|
||||||
|
@ -1034,7 +1034,13 @@ proc finalize_testing {} {
|
|||||||
output2 "[expr {$nErr-$nKnown}] new errors and $nKnown known errors\
|
output2 "[expr {$nErr-$nKnown}] new errors and $nKnown known errors\
|
||||||
out of $nTest tests"
|
out of $nTest tests"
|
||||||
} else {
|
} else {
|
||||||
output2 "$nErr errors out of $nTest tests"
|
set cpuinfo {}
|
||||||
|
if {[catch {exec hostname} hname]==0} {set cpuinfo [string trim $hname]}
|
||||||
|
append cpuinfo " $::tcl_platform(os)"
|
||||||
|
append cpuinfo " [expr {$::tcl_platform(pointerSize)*8}]-bit"
|
||||||
|
append cpuinfo " [string map {E -e} $::tcl_platform(byteOrder)]"
|
||||||
|
output2 "SQLite [sqlite3 -sourceid]"
|
||||||
|
output2 "$nErr errors out of $nTest tests on $cpuinfo"
|
||||||
}
|
}
|
||||||
if {$nErr>$nKnown} {
|
if {$nErr>$nKnown} {
|
||||||
output2 -nonewline "!Failures on these tests:"
|
output2 -nonewline "!Failures on these tests:"
|
||||||
|
@ -68,19 +68,19 @@ set x7 backbone
|
|||||||
set x8 backarrow
|
set x8 backarrow
|
||||||
set x9 castle
|
set x9 castle
|
||||||
|
|
||||||
db func glob gfunc
|
db func glob -argcount 2 gfunc
|
||||||
proc gfunc {a b} {
|
proc gfunc {a b} {
|
||||||
incr ::gfunc
|
incr ::gfunc
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
db func like lfunc
|
db func like -argcount 2 lfunc
|
||||||
proc lfunc {a b} {
|
proc lfunc {a b} {
|
||||||
incr ::gfunc 100
|
incr ::gfunc 100
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
db func regexp rfunc
|
db func regexp -argcount 2 rfunc
|
||||||
proc rfunc {a b} {
|
proc rfunc {a b} {
|
||||||
incr ::gfunc 10000
|
incr ::gfunc 10000
|
||||||
return 1
|
return 1
|
||||||
|
@ -712,7 +712,7 @@ do_test wal-11.5 {
|
|||||||
do_test wal-11.6 {
|
do_test wal-11.6 {
|
||||||
execsql COMMIT
|
execsql COMMIT
|
||||||
list [expr [file size test.db]/1024] [file size test.db-wal]
|
list [expr [file size test.db]/1024] [file size test.db-wal]
|
||||||
} [list 3 [wal_file_size 41 1024]]
|
} [list 3 [wal_file_size 40 1024]]
|
||||||
do_test wal-11.7 {
|
do_test wal-11.7 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT count(*) FROM t1;
|
SELECT count(*) FROM t1;
|
||||||
@ -722,15 +722,22 @@ do_test wal-11.7 {
|
|||||||
do_test wal-11.8 {
|
do_test wal-11.8 {
|
||||||
execsql { PRAGMA wal_checkpoint }
|
execsql { PRAGMA wal_checkpoint }
|
||||||
list [expr [file size test.db]/1024] [file size test.db-wal]
|
list [expr [file size test.db]/1024] [file size test.db-wal]
|
||||||
} [list 37 [wal_file_size 41 1024]]
|
} [list 37 [wal_file_size 40 1024]]
|
||||||
do_test wal-11.9 {
|
do_test wal-11.9 {
|
||||||
db close
|
db close
|
||||||
list [expr [file size test.db]/1024] [log_deleted test.db-wal]
|
list [expr [file size test.db]/1024] [log_deleted test.db-wal]
|
||||||
} {37 1}
|
} {37 1}
|
||||||
sqlite3_wal db test.db
|
sqlite3_wal db test.db
|
||||||
set nWal 39
|
|
||||||
if {[permutation]!="mmap"} {set nWal 37}
|
# After adding the capability of WAL to overwrite prior uncommitted
|
||||||
ifcapable !mmap {set nWal 37}
|
# frame in the WAL-file with revised content, the size of the WAL file
|
||||||
|
# following cache-spill is smaller.
|
||||||
|
#
|
||||||
|
#set nWal 39
|
||||||
|
#if {[permutation]!="mmap"} {set nWal 37}
|
||||||
|
#ifcapable !mmap {set nWal 37}
|
||||||
|
set nWal 34
|
||||||
|
|
||||||
do_test wal-11.10 {
|
do_test wal-11.10 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA cache_size = 10;
|
PRAGMA cache_size = 10;
|
||||||
|
164
test/waloverwrite.test
Normal file
164
test/waloverwrite.test
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
# 2010 May 5
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
# This file implements regression tests for SQLite library. The
|
||||||
|
# focus of this file is testing the operation of the library in
|
||||||
|
# "PRAGMA journal_mode=WAL" mode.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
source $testdir/wal_common.tcl
|
||||||
|
set testprefix waloverwrite
|
||||||
|
|
||||||
|
ifcapable !wal {finish_test ; return }
|
||||||
|
|
||||||
|
# Simple test:
|
||||||
|
#
|
||||||
|
# Test cases *.1 - *.6:
|
||||||
|
#
|
||||||
|
# + Create a database of blobs roughly 50 pages in size.
|
||||||
|
#
|
||||||
|
# + Set the db cache size to something much smaller than this (5 pages)
|
||||||
|
#
|
||||||
|
# + Within a transaction, loop through the set of blobs 5 times. Update
|
||||||
|
# each blob as it is visited.
|
||||||
|
#
|
||||||
|
# + Test that the wal file is roughly 50 pages in size - even though many
|
||||||
|
# database pages have been written to it multiple times.
|
||||||
|
#
|
||||||
|
# + Take a copy of the database and wal file. Test that recovery can
|
||||||
|
# be run on it.
|
||||||
|
#
|
||||||
|
# Test cases *.7 - *.9:
|
||||||
|
#
|
||||||
|
# + Same thing, but before committing the statement transaction open
|
||||||
|
# a SAVEPOINT, update the blobs another 5 times, then roll it back.
|
||||||
|
#
|
||||||
|
# + Check that if recovery is run on the resulting wal file, the rolled
|
||||||
|
# back changes from within the SAVEPOINT are not present in the db.
|
||||||
|
#
|
||||||
|
# The above is run twice - once where the wal file is empty at the start of
|
||||||
|
# step 3 (tn==1) and once where it already contains a transaction (tn==2).
|
||||||
|
#
|
||||||
|
foreach {tn xtra} {
|
||||||
|
1 {}
|
||||||
|
2 { UPDATE t1 SET y = randomblob(799) WHERE x=4 }
|
||||||
|
} {
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 1.$tn.0 {
|
||||||
|
CREATE TABLE t1(x, y);
|
||||||
|
CREATE TABLE t2(x, y);
|
||||||
|
CREATE INDEX i1y ON t1(y);
|
||||||
|
|
||||||
|
WITH cnt(i) AS (
|
||||||
|
SELECT 1 UNION ALL SELECT i+1 FROM cnt WHERE i<20
|
||||||
|
)
|
||||||
|
INSERT INTO t1 SELECT i, randomblob(800) FROM cnt;
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_test 1.$tn.1 {
|
||||||
|
set nPg [db one { PRAGMA page_count } ]
|
||||||
|
expr $nPg>40 && $nPg<50
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
do_test 1.$tn.2 {
|
||||||
|
db close
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
|
execsql {PRAGMA journal_mode = wal}
|
||||||
|
execsql {PRAGMA cache_size = 5}
|
||||||
|
execsql $xtra
|
||||||
|
|
||||||
|
db transaction {
|
||||||
|
for {set i 0} {$i < 5} {incr i} {
|
||||||
|
foreach x [db eval {SELECT x FROM t1}] {
|
||||||
|
execsql { UPDATE t1 SET y = randomblob(799) WHERE x=$x }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set nPg [wal_frame_count test.db-wal 1024]
|
||||||
|
expr $nPg>40 && $nPg<60
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
do_execsql_test 1.$tn.3 { PRAGMA integrity_check } ok
|
||||||
|
|
||||||
|
do_test 1.$tn.4 {
|
||||||
|
forcedelete test.db2 test.db2-wal
|
||||||
|
forcecopy test.db test.db2
|
||||||
|
sqlite3 db2 test.db2
|
||||||
|
execsql { SELECT sum(length(y)) FROM t1 } db2
|
||||||
|
} [expr 20*800]
|
||||||
|
|
||||||
|
do_test 1.$tn.5 {
|
||||||
|
db2 close
|
||||||
|
forcecopy test.db test.db2
|
||||||
|
forcecopy test.db-wal test.db2-wal
|
||||||
|
sqlite3 db2 test.db2
|
||||||
|
execsql { SELECT sum(length(y)) FROM t1 } db2
|
||||||
|
} [expr 20*799]
|
||||||
|
|
||||||
|
do_test 1.$tn.6 {
|
||||||
|
execsql { PRAGMA integrity_check } db2
|
||||||
|
} ok
|
||||||
|
db2 close
|
||||||
|
|
||||||
|
do_test 1.$tn.7 {
|
||||||
|
execsql { PRAGMA wal_checkpoint }
|
||||||
|
db transaction {
|
||||||
|
for {set i 0} {$i < 1} {incr i} {
|
||||||
|
foreach x [db eval {SELECT x FROM t1}] {
|
||||||
|
execsql { UPDATE t1 SET y = randomblob(798) WHERE x=$x }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
execsql {
|
||||||
|
WITH cnt(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM cnt WHERE i<20)
|
||||||
|
INSERT INTO t2 SELECT i, randomblob(800) FROM cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
execsql {SAVEPOINT abc}
|
||||||
|
for {set i 0} {$i < 5} {incr i} {
|
||||||
|
foreach x [db eval {SELECT x FROM t1}] {
|
||||||
|
execsql { UPDATE t1 SET y = randomblob(797) WHERE x=$x }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
breakpoint
|
||||||
|
execsql {ROLLBACK TO abc}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
set nPg [wal_frame_count test.db-wal 1024]
|
||||||
|
expr $nPg>55 && $nPg<75
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
do_test 1.$tn.8 {
|
||||||
|
forcedelete test.db2 test.db2-wal
|
||||||
|
forcecopy test.db test.db2
|
||||||
|
sqlite3 db2 test.db2
|
||||||
|
execsql { SELECT sum(length(y)) FROM t1 } db2
|
||||||
|
} [expr 20*799]
|
||||||
|
|
||||||
|
do_test 1.$tn.9 {
|
||||||
|
db2 close
|
||||||
|
forcecopy test.db-wal test.db2-wal
|
||||||
|
sqlite3 db2 test.db2
|
||||||
|
execsql { SELECT sum(length(y)) FROM t1 } db2
|
||||||
|
} [expr 20*798]
|
||||||
|
|
||||||
|
do_test 1.$tn.9 {
|
||||||
|
execsql { PRAGMA integrity_check } db2
|
||||||
|
} ok
|
||||||
|
db2 close
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_test
|
||||||
|
|
Reference in New Issue
Block a user