mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-15 11:41:13 +03:00
Merge with main branch.
FossilOrigin-Name: 6e09e28751a7071969ef9f3445f4092d2c28f358
This commit is contained in:
BIN
art/src_logo.gif
Normal file
BIN
art/src_logo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
20
configure
vendored
20
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.62 for sqlite 3.6.17.
|
# Generated by GNU Autoconf 2.62 for sqlite 3.6.18.
|
||||||
#
|
#
|
||||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||||
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||||
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='sqlite'
|
PACKAGE_NAME='sqlite'
|
||||||
PACKAGE_TARNAME='sqlite'
|
PACKAGE_TARNAME='sqlite'
|
||||||
PACKAGE_VERSION='3.6.17'
|
PACKAGE_VERSION='3.6.18'
|
||||||
PACKAGE_STRING='sqlite 3.6.17'
|
PACKAGE_STRING='sqlite 3.6.18'
|
||||||
PACKAGE_BUGREPORT=''
|
PACKAGE_BUGREPORT=''
|
||||||
|
|
||||||
# Factoring default headers for most tests.
|
# Factoring default headers for most tests.
|
||||||
@@ -1487,7 +1487,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.6.17 to adapt to many kinds of systems.
|
\`configure' configures sqlite 3.6.18 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@@ -1552,7 +1552,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.6.17:";;
|
short | recursive ) echo "Configuration of sqlite 3.6.18:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@@ -1670,7 +1670,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.6.17
|
sqlite configure 3.6.18
|
||||||
generated by GNU Autoconf 2.62
|
generated by GNU Autoconf 2.62
|
||||||
|
|
||||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||||
@@ -1684,7 +1684,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.6.17, which was
|
It was created by sqlite $as_me 3.6.18, which was
|
||||||
generated by GNU Autoconf 2.62. Invocation command line was
|
generated by GNU Autoconf 2.62. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
@@ -2065,7 +2065,7 @@ please regen with autoconf" >&2;}
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# The following RCS revision string applies to configure.in
|
# The following RCS revision string applies to configure.in
|
||||||
# $Revision: 1.74 $
|
# $Revision: 1.56 $
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# Programs needed
|
# Programs needed
|
||||||
@@ -13972,7 +13972,7 @@ exec 6>&1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by sqlite $as_me 3.6.17, which was
|
This file was extended by sqlite $as_me 3.6.18, which was
|
||||||
generated by GNU Autoconf 2.62. Invocation command line was
|
generated by GNU Autoconf 2.62. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@@ -14025,7 +14025,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
|||||||
_ACEOF
|
_ACEOF
|
||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
sqlite config.status 3.6.17
|
sqlite config.status 3.6.18
|
||||||
configured by $0, generated by GNU Autoconf 2.62,
|
configured by $0, generated by GNU Autoconf 2.62,
|
||||||
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||||
|
|
||||||
|
|||||||
27
manifest
27
manifest
@@ -1,11 +1,11 @@
|
|||||||
C Fix\sanother\stest\sproblem\sand\ssome\sinstances\swhere\san\sOOM\smay\scause\sa\ssegfault.
|
C Merge\swith\smain\sbranch.
|
||||||
D 2009-08-31T05:23:33
|
D 2009-08-31T05:39:59
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 73ddeec9dd10b85876c5c2ce1fdce627e1dcc7f8
|
F Makefile.in 73ddeec9dd10b85876c5c2ce1fdce627e1dcc7f8
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
F Makefile.vxworks 10010ddbf52e2503c7c49c7c0b7c7a096f8638a6
|
F Makefile.vxworks 10010ddbf52e2503c7c49c7c0b7c7a096f8638a6
|
||||||
F README b974cdc3f9f12b87e851b04e75996d720ebf81ac
|
F README b974cdc3f9f12b87e851b04e75996d720ebf81ac
|
||||||
F VERSION 8fd162479ea9d3932d4492a889db80634742fe90
|
F VERSION 7260e7baf934051dee42458206e915b75570f41d
|
||||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||||
F addopcodes.awk 215333be9d99c260e076c3080a81dba3ae928c45
|
F addopcodes.awk 215333be9d99c260e076c3080a81dba3ae928c45
|
||||||
F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248
|
F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248
|
||||||
@@ -15,10 +15,11 @@ F art/SQLiteLogo3.tiff b9e6bf022ae939bc986cddb8ab99583ca1b02cb3
|
|||||||
F art/SQLite_big.gif 2b8e4603b91ba2a2c7062a82ff570d945034bb30
|
F art/SQLite_big.gif 2b8e4603b91ba2a2c7062a82ff570d945034bb30
|
||||||
F art/nocopy.gif 716aa07d4bb7250d4e75756073bf8ef9f56bec8f
|
F art/nocopy.gif 716aa07d4bb7250d4e75756073bf8ef9f56bec8f
|
||||||
F art/powered_by_sqlite.gif 7fbcd7d3675391fd3d21672c14c05f5999eb60d1
|
F art/powered_by_sqlite.gif 7fbcd7d3675391fd3d21672c14c05f5999eb60d1
|
||||||
|
F art/src_logo.gif 9341ef09f0e53cd44c0c9b6fc3c16f7f3d6c2ad9
|
||||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||||
F config.h.in 868fdb48c028421a203470e15c69ada15b9ba673
|
F config.h.in 868fdb48c028421a203470e15c69ada15b9ba673
|
||||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||||
F configure 486c870218ec915bd8edfece7109b6c864e82a5a
|
F configure bccfdabb9982b7e88a33470741f1d6ba14a6b684
|
||||||
F configure.ac 14740970ddb674d92a9f5da89083dff1179014ff
|
F configure.ac 14740970ddb674d92a9f5da89083dff1179014ff
|
||||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||||
F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
|
F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
|
||||||
@@ -105,7 +106,7 @@ F src/auth.c 802a9439dfa0b8c208b10055cba400e82ef18025
|
|||||||
F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3
|
F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3
|
||||||
F src/bitvec.c e08f6c1a9551b88081fc737916c6c3fd5029a6cf
|
F src/bitvec.c e08f6c1a9551b88081fc737916c6c3fd5029a6cf
|
||||||
F src/btmutex.c 0f43a75bb5b8147b386e8e1c3e71ba734e3863b7
|
F src/btmutex.c 0f43a75bb5b8147b386e8e1c3e71ba734e3863b7
|
||||||
F src/btree.c 49212ddaee8d7d12b4f1e17b9de62f7ea91ca59d
|
F src/btree.c 6b60ece56141bbe23aa6efca10f1612d34271c2f
|
||||||
F src/btree.h 577448a890c2ab9b21e6ab74f073526184bceebe
|
F src/btree.h 577448a890c2ab9b21e6ab74f073526184bceebe
|
||||||
F src/btreeInt.h 1c86297e69380f6577e7ae67452597dd8d5c2705
|
F src/btreeInt.h 1c86297e69380f6577e7ae67452597dd8d5c2705
|
||||||
F src/build.c 212476dc971756e7f7429e677059fafc678afbd5
|
F src/build.c 212476dc971756e7f7429e677059fafc678afbd5
|
||||||
@@ -144,7 +145,7 @@ F src/os.c 9fea283e336ee31caa4654d6cb05a129a1c42d2f
|
|||||||
F src/os.h 00a1334a4eecee7f7bef79ac606b88d325119f21
|
F src/os.h 00a1334a4eecee7f7bef79ac606b88d325119f21
|
||||||
F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc
|
F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc
|
||||||
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
|
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
|
||||||
F src/os_unix.c 1546de71b888c9a2bb0589d04e7e4267d40ef944
|
F src/os_unix.c f14ff07aec3c3c0796e1a743d1bdafddc15d1af1
|
||||||
F src/os_win.c 58bb163f327e79726dd119344d908e4d98483c3f
|
F src/os_win.c 58bb163f327e79726dd119344d908e4d98483c3f
|
||||||
F src/pager.c a47be286477ed6c7b9a342dd53d4e4043f29d8c2
|
F src/pager.c a47be286477ed6c7b9a342dd53d4e4043f29d8c2
|
||||||
F src/pager.h 11852d044c86cf5a9d6e34171fb0c4fcf1f6265f
|
F src/pager.h 11852d044c86cf5a9d6e34171fb0c4fcf1f6265f
|
||||||
@@ -160,7 +161,7 @@ F src/resolve.c 92ef8a85d53b305a7de9faef27d652b96c2b4db6
|
|||||||
F src/rowset.c c64dafba1f9fd876836c8db8682966b9d197eb1f
|
F src/rowset.c c64dafba1f9fd876836c8db8682966b9d197eb1f
|
||||||
F src/select.c 56ecb073e6f6696173ad80493aa14355225b6e53
|
F src/select.c 56ecb073e6f6696173ad80493aa14355225b6e53
|
||||||
F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb
|
F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb
|
||||||
F src/sqlite.h.in 3ccf717d82101f19548d0b1243f0a6f4854d51ee
|
F src/sqlite.h.in 9d03ceaad971882482c158c0e3d39d361c2c18a1
|
||||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||||
F src/sqliteInt.h d87eb4976edacb68fb9b7557163ae0def733354b
|
F src/sqliteInt.h d87eb4976edacb68fb9b7557163ae0def733354b
|
||||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
||||||
@@ -208,12 +209,12 @@ F src/vdbe.c 5e9d870ec390fbc329f11424b121681e8da5d75c
|
|||||||
F src/vdbe.h 080fe6bc1264438becb8bf9b9f3c84074c336b78
|
F src/vdbe.h 080fe6bc1264438becb8bf9b9f3c84074c336b78
|
||||||
F src/vdbeInt.h 1291908344bcbaa8cf47de86d7108cb92c3a71a3
|
F src/vdbeInt.h 1291908344bcbaa8cf47de86d7108cb92c3a71a3
|
||||||
F src/vdbeapi.c 8d5013ab6104be757c208a70ffb191cc27d2b688
|
F src/vdbeapi.c 8d5013ab6104be757c208a70ffb191cc27d2b688
|
||||||
F src/vdbeaux.c d8ca68164d20c5b65dfa713095febcb5d37d45b0
|
F src/vdbeaux.c 1cc9dd48848059d1c1cd05775659323e0a8654dc
|
||||||
F src/vdbeblob.c f93cb60ac388633ed3bde8a94ef161ad2dbfb689
|
F src/vdbeblob.c f93cb60ac388633ed3bde8a94ef161ad2dbfb689
|
||||||
F src/vdbemem.c dc551981833756ea34a3e0b238f759479e7cf526
|
F src/vdbemem.c dc551981833756ea34a3e0b238f759479e7cf526
|
||||||
F src/vtab.c 10df5c77cea34a49f2ad4e5de763f820d6223eb4
|
F src/vtab.c 10df5c77cea34a49f2ad4e5de763f820d6223eb4
|
||||||
F src/walker.c 1edca756275f158b80f20eb6f104c8d3fcc96a04
|
F src/walker.c 1edca756275f158b80f20eb6f104c8d3fcc96a04
|
||||||
F src/where.c b9ad2d2db4a7d1cda7bed8a7299eb73fde63b5b1
|
F src/where.c a3218dfcf32e3d933270b76a72b97065f24b3f2c
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||||
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
|
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
|
||||||
@@ -663,7 +664,7 @@ F test/tkt3929.test 6a4c3baefb4e75127356b7d675b5df42c35c00d1
|
|||||||
F test/tkt3935.test e15261fedb9e30a4305a311da614a5d8e693c767
|
F test/tkt3935.test e15261fedb9e30a4305a311da614a5d8e693c767
|
||||||
F test/tkt3992.test 2ba939cc646eaa46761dfd55f975cad69bf4e254
|
F test/tkt3992.test 2ba939cc646eaa46761dfd55f975cad69bf4e254
|
||||||
F test/tkt3997.test a335fa41ca3985660a139df7b734a26ef53284bd
|
F test/tkt3997.test a335fa41ca3985660a139df7b734a26ef53284bd
|
||||||
F test/tkt4018.test f581cf52dc359171875cb649bdc38b525d7b9309
|
F test/tkt4018.test 7c2c9ba4df489c676a0a7a0e809a1fb9b2185bd1
|
||||||
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
||||||
F test/trace.test 19ffbc09885c3321d56358a5738feae8587fb377
|
F test/trace.test 19ffbc09885c3321d56358a5738feae8587fb377
|
||||||
F test/trans.test d887cb07630dc39879a322d958ad8b006137485c
|
F test/trans.test d887cb07630dc39879a322d958ad8b006137485c
|
||||||
@@ -747,7 +748,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
||||||
P 9eb91efda5241609ff18ff15ef5eaa0e86788eab
|
P 31199db0f77cf4b32d5589a29abd9535b155164b 6abcba1021b237452f542f1fbb69eb75d9f50f53
|
||||||
R 63b174d38f0bc479f8becc3f97b1ed05
|
R 31e80012e316e6ca372fbf461bf4b6ab
|
||||||
U dan
|
U dan
|
||||||
Z 2a154fc741e40d1c8378264e43f74ea7
|
Z 33710f063b4132081e125750db8134c3
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
31199db0f77cf4b32d5589a29abd9535b155164b
|
6e09e28751a7071969ef9f3445f4092d2c28f358
|
||||||
@@ -4346,9 +4346,12 @@ int sqlite3BtreeMovetoUnpacked(
|
|||||||
goto moveto_finish;
|
goto moveto_finish;
|
||||||
}
|
}
|
||||||
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
|
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
|
||||||
|
if( rc ){
|
||||||
|
sqlite3_free(pCellKey);
|
||||||
|
goto moveto_finish;
|
||||||
|
}
|
||||||
c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
|
c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
|
||||||
sqlite3_free(pCellKey);
|
sqlite3_free(pCellKey);
|
||||||
if( rc ) goto moveto_finish;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( c==0 ){
|
if( c==0 ){
|
||||||
|
|||||||
280
src/os_unix.c
280
src/os_unix.c
@@ -167,6 +167,19 @@
|
|||||||
#define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY))
|
#define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Sometimes, after a file handle is closed by SQLite, the file descriptor
|
||||||
|
** cannot be closed immediately. In these cases, instances of the following
|
||||||
|
** structure are used to store the file descriptor while waiting for an
|
||||||
|
** opportunity to either close or reuse it.
|
||||||
|
*/
|
||||||
|
typedef struct UnixUnusedFd UnixUnusedFd;
|
||||||
|
struct UnixUnusedFd {
|
||||||
|
int fd; /* File descriptor to close */
|
||||||
|
int flags; /* Flags this file descriptor was opened with */
|
||||||
|
UnixUnusedFd *pNext; /* Next unused file descriptor on same file */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The unixFile structure is subclass of sqlite3_file specific to the unix
|
** The unixFile structure is subclass of sqlite3_file specific to the unix
|
||||||
** VFS implementations.
|
** VFS implementations.
|
||||||
@@ -181,7 +194,7 @@ struct unixFile {
|
|||||||
unsigned char locktype; /* The type of lock held on this fd */
|
unsigned char locktype; /* The type of lock held on this fd */
|
||||||
int lastErrno; /* The unix errno from the last I/O error */
|
int lastErrno; /* The unix errno from the last I/O error */
|
||||||
void *lockingContext; /* Locking style specific state */
|
void *lockingContext; /* Locking style specific state */
|
||||||
int flags; /* Flags value returned by xOpen() */
|
UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||||
int openFlags; /* The flags specified at open() */
|
int openFlags; /* The flags specified at open() */
|
||||||
#endif
|
#endif
|
||||||
@@ -748,14 +761,10 @@ struct unixOpenCnt {
|
|||||||
struct unixFileId fileId; /* The lookup key */
|
struct unixFileId fileId; /* The lookup key */
|
||||||
int nRef; /* Number of pointers to this structure */
|
int nRef; /* Number of pointers to this structure */
|
||||||
int nLock; /* Number of outstanding locks */
|
int nLock; /* Number of outstanding locks */
|
||||||
int nPending; /* Number of pending close() operations */
|
UnixUnusedFd *pUnused; /* Unused file descriptors to close */
|
||||||
struct PendingClose {
|
|
||||||
int fd; /* File descriptor to close */
|
|
||||||
int flags; /* Flags this file descriptor was opened with */
|
|
||||||
} *aPending; /* Malloced space holding fds awaiting close() */
|
|
||||||
#if OS_VXWORKS
|
#if OS_VXWORKS
|
||||||
sem_t *pSem; /* Named POSIX semaphore */
|
sem_t *pSem; /* Named POSIX semaphore */
|
||||||
char aSemName[MAX_PATHNAME+1]; /* Name of that semaphore */
|
char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */
|
||||||
#endif
|
#endif
|
||||||
struct unixOpenCnt *pNext, *pPrev; /* List of all unixOpenCnt objects */
|
struct unixOpenCnt *pNext, *pPrev; /* List of all unixOpenCnt objects */
|
||||||
};
|
};
|
||||||
@@ -910,7 +919,7 @@ static void releaseOpenCnt(struct unixOpenCnt *pOpen){
|
|||||||
assert( pOpen->pNext->pPrev==pOpen );
|
assert( pOpen->pNext->pPrev==pOpen );
|
||||||
pOpen->pNext->pPrev = pOpen->pPrev;
|
pOpen->pNext->pPrev = pOpen->pPrev;
|
||||||
}
|
}
|
||||||
sqlite3_free(pOpen->aPending);
|
assert( !pOpen->pUnused );
|
||||||
sqlite3_free(pOpen);
|
sqlite3_free(pOpen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1028,19 +1037,12 @@ static int findLockInfo(
|
|||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
goto exit_findlockinfo;
|
goto exit_findlockinfo;
|
||||||
}
|
}
|
||||||
|
memset(pOpen, 0, sizeof(*pOpen));
|
||||||
pOpen->fileId = fileId;
|
pOpen->fileId = fileId;
|
||||||
pOpen->nRef = 1;
|
pOpen->nRef = 1;
|
||||||
pOpen->nLock = 0;
|
|
||||||
pOpen->nPending = 0;
|
|
||||||
pOpen->aPending = 0;
|
|
||||||
pOpen->pNext = openList;
|
pOpen->pNext = openList;
|
||||||
pOpen->pPrev = 0;
|
|
||||||
if( openList ) openList->pPrev = pOpen;
|
if( openList ) openList->pPrev = pOpen;
|
||||||
openList = pOpen;
|
openList = pOpen;
|
||||||
#if OS_VXWORKS
|
|
||||||
pOpen->pSem = NULL;
|
|
||||||
pOpen->aSemName[0] = '\0';
|
|
||||||
#endif
|
|
||||||
}else{
|
}else{
|
||||||
pOpen->nRef++;
|
pOpen->nRef++;
|
||||||
}
|
}
|
||||||
@@ -1405,57 +1407,46 @@ end_lock:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Close all file descriptors accumuated in the p->aPending[] array. If
|
** Close all file descriptors accumuated in the unixOpenCnt->pUnused list.
|
||||||
** all such file descriptors are closed without error, the aPending[]
|
** If all such file descriptors are closed without error, the list is
|
||||||
** array is deleted and SQLITE_OK returned.
|
** cleared and SQLITE_OK returned.
|
||||||
**
|
**
|
||||||
** Otherwise, if an error occurs, then successfully closed file descriptor
|
** Otherwise, if an error occurs, then successfully closed file descriptor
|
||||||
** entries in the aPending[] array are set to -1, the aPending[] array
|
** entries are removed from the list, and SQLITE_IOERR_CLOSE returned.
|
||||||
** not deleted and SQLITE_IOERR_CLOSE returned.
|
** not deleted and SQLITE_IOERR_CLOSE returned.
|
||||||
*/
|
*/
|
||||||
static int closePendingFds(unixFile *pFile){
|
static int closePendingFds(unixFile *pFile){
|
||||||
struct unixOpenCnt *pOpen = pFile->pOpen;
|
|
||||||
struct PendingClose *aPending = pOpen->aPending;
|
|
||||||
int i;
|
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
assert( unixMutexHeld() );
|
struct unixOpenCnt *pOpen = pFile->pOpen;
|
||||||
for(i=0; i<pOpen->nPending; i++){
|
UnixUnusedFd *pError = 0;
|
||||||
if( aPending[i].fd>=0 ){
|
UnixUnusedFd *p;
|
||||||
if( close(aPending[i].fd) ){
|
UnixUnusedFd *pNext;
|
||||||
|
for(p=pOpen->pUnused; p; p=pNext){
|
||||||
|
pNext = p->pNext;
|
||||||
|
if( close(p->fd) ){
|
||||||
pFile->lastErrno = errno;
|
pFile->lastErrno = errno;
|
||||||
rc = SQLITE_IOERR_CLOSE;
|
rc = SQLITE_IOERR_CLOSE;
|
||||||
|
p->pNext = pError;
|
||||||
|
pError = p;
|
||||||
}else{
|
}else{
|
||||||
aPending[i].fd = -1;
|
sqlite3_free(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
pOpen->pUnused = pError;
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
sqlite3_free(aPending);
|
|
||||||
pOpen->nPending = 0;
|
|
||||||
pOpen->aPending = 0;
|
|
||||||
}
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Add the file descriptor used by file handle pFile to the corresponding
|
** Add the file descriptor used by file handle pFile to the corresponding
|
||||||
** aPending[] array to be closed after some other connection releases
|
** pUnused list.
|
||||||
** a lock.
|
|
||||||
*/
|
*/
|
||||||
static void setPendingFd(unixFile *pFile){
|
static void setPendingFd(unixFile *pFile){
|
||||||
struct PendingClose *aNew;
|
|
||||||
struct unixOpenCnt *pOpen = pFile->pOpen;
|
struct unixOpenCnt *pOpen = pFile->pOpen;
|
||||||
int nByte = (pOpen->nPending+1)*sizeof(pOpen->aPending[0]);
|
UnixUnusedFd *p = pFile->pUnused;
|
||||||
aNew = sqlite3_realloc(pOpen->aPending, nByte);
|
p->pNext = pOpen->pUnused;
|
||||||
if( aNew==0 ){
|
pOpen->pUnused = p;
|
||||||
/* If a malloc fails, just leak the file descriptor */
|
|
||||||
}else{
|
|
||||||
pOpen->aPending = aNew;
|
|
||||||
pOpen->aPending[pOpen->nPending].fd = pFile->h;
|
|
||||||
pOpen->aPending[pOpen->nPending].flags = pFile->flags;
|
|
||||||
pOpen->nPending++;
|
|
||||||
pFile->h = -1;
|
pFile->h = -1;
|
||||||
}
|
pFile->pUnused = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1573,7 +1564,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){
|
|||||||
pOpen = pFile->pOpen;
|
pOpen = pFile->pOpen;
|
||||||
pOpen->nLock--;
|
pOpen->nLock--;
|
||||||
assert( pOpen->nLock>=0 );
|
assert( pOpen->nLock>=0 );
|
||||||
if( pOpen->nLock==0 && pOpen->nPending>0 ){
|
if( pOpen->nLock==0 ){
|
||||||
int rc2 = closePendingFds(pFile);
|
int rc2 = closePendingFds(pFile);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = rc2;
|
rc = rc2;
|
||||||
@@ -1627,6 +1618,7 @@ static int closeUnixFile(sqlite3_file *id){
|
|||||||
#endif
|
#endif
|
||||||
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
||||||
OpenCounter(-1);
|
OpenCounter(-1);
|
||||||
|
sqlite3_free(pFile->pUnused);
|
||||||
memset(pFile, 0, sizeof(unixFile));
|
memset(pFile, 0, sizeof(unixFile));
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@@ -1644,8 +1636,8 @@ static int unixClose(sqlite3_file *id){
|
|||||||
if( pFile->pOpen && pFile->pOpen->nLock ){
|
if( pFile->pOpen && pFile->pOpen->nLock ){
|
||||||
/* If there are outstanding locks, do not actually close the file just
|
/* If there are outstanding locks, do not actually close the file just
|
||||||
** yet because that would clear those locks. Instead, add the file
|
** yet because that would clear those locks. Instead, add the file
|
||||||
** descriptor to pOpen->aPending. It will be automatically closed when
|
** descriptor to pOpen->pUnused list. It will be automatically closed
|
||||||
** the last lock is cleared.
|
** when the last lock is cleared.
|
||||||
*/
|
*/
|
||||||
setPendingFd(pFile);
|
setPendingFd(pFile);
|
||||||
}
|
}
|
||||||
@@ -2616,7 +2608,7 @@ static int afpUnlock(sqlite3_file *id, int locktype) {
|
|||||||
struct unixOpenCnt *pOpen = pFile->pOpen;
|
struct unixOpenCnt *pOpen = pFile->pOpen;
|
||||||
pOpen->nLock--;
|
pOpen->nLock--;
|
||||||
assert( pOpen->nLock>=0 );
|
assert( pOpen->nLock>=0 );
|
||||||
if( pOpen->nLock==0 && pOpen->nPending>0 ){
|
if( pOpen->nLock==0 ){
|
||||||
rc = closePendingFds(pFile);
|
rc = closePendingFds(pFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2734,7 +2726,7 @@ static int unixRead(
|
|||||||
|
|
||||||
/* If this is a database file (not a journal, master-journal or temp
|
/* If this is a database file (not a journal, master-journal or temp
|
||||||
** file), the bytes in the locking range should never be read or written. */
|
** file), the bytes in the locking range should never be read or written. */
|
||||||
assert( (pFile->flags&SQLITE_OPEN_MAIN_DB)==0
|
assert( pFile->pUnused==0
|
||||||
|| offset>=PENDING_BYTE+512
|
|| offset>=PENDING_BYTE+512
|
||||||
|| offset+amt<=PENDING_BYTE
|
|| offset+amt<=PENDING_BYTE
|
||||||
);
|
);
|
||||||
@@ -2807,7 +2799,7 @@ static int unixWrite(
|
|||||||
|
|
||||||
/* If this is a database file (not a journal, master-journal or temp
|
/* If this is a database file (not a journal, master-journal or temp
|
||||||
** file), the bytes in the locking range should never be read or written. */
|
** file), the bytes in the locking range should never be read or written. */
|
||||||
assert( (pFile->flags&SQLITE_OPEN_MAIN_DB)==0
|
assert( pFile->pUnused==0
|
||||||
|| offset>=PENDING_BYTE+512
|
|| offset>=PENDING_BYTE+512
|
||||||
|| offset+amt<=PENDING_BYTE
|
|| offset+amt<=PENDING_BYTE
|
||||||
);
|
);
|
||||||
@@ -3174,7 +3166,7 @@ static int unixDeviceCharacteristics(sqlite3_file *NotUsed){
|
|||||||
**
|
**
|
||||||
** (1) The real finder-function named "FImpt()".
|
** (1) The real finder-function named "FImpt()".
|
||||||
**
|
**
|
||||||
** (2) A constant pointer to this functio named just "F".
|
** (2) A constant pointer to this function named just "F".
|
||||||
**
|
**
|
||||||
**
|
**
|
||||||
** A pointer to the F pointer is used as the pAppData value for VFS
|
** A pointer to the F pointer is used as the pAppData value for VFS
|
||||||
@@ -3438,13 +3430,10 @@ static int fillInUnixFile(
|
|||||||
assert( pNew->pLock==NULL );
|
assert( pNew->pLock==NULL );
|
||||||
assert( pNew->pOpen==NULL );
|
assert( pNew->pOpen==NULL );
|
||||||
|
|
||||||
/* Parameter isDelete is only used on vxworks.
|
/* Parameter isDelete is only used on vxworks. Express this explicitly
|
||||||
** Express this explicitly here to prevent compiler warnings
|
** here to prevent compiler warnings about unused parameters.
|
||||||
** about unused parameters.
|
|
||||||
*/
|
*/
|
||||||
#if !OS_VXWORKS
|
|
||||||
UNUSED_PARAMETER(isDelete);
|
UNUSED_PARAMETER(isDelete);
|
||||||
#endif
|
|
||||||
|
|
||||||
OSTRACE3("OPEN %-3d %s\n", h, zFilename);
|
OSTRACE3("OPEN %-3d %s\n", h, zFilename);
|
||||||
pNew->h = h;
|
pNew->h = h;
|
||||||
@@ -3474,6 +3463,28 @@ static int fillInUnixFile(
|
|||||||
if( pLockingStyle == &posixIoMethods ){
|
if( pLockingStyle == &posixIoMethods ){
|
||||||
unixEnterMutex();
|
unixEnterMutex();
|
||||||
rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
|
rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
/* If an error occured in findLockInfo(), close the file descriptor
|
||||||
|
** immediately, before releasing the mutex. findLockInfo() may fail
|
||||||
|
** in two scenarios:
|
||||||
|
**
|
||||||
|
** (a) A call to fstat() failed.
|
||||||
|
** (b) A malloc failed.
|
||||||
|
**
|
||||||
|
** Scenario (b) may only occur if the process is holding no other
|
||||||
|
** file descriptors open on the same file. If there were other file
|
||||||
|
** descriptors on this file, then no malloc would be required by
|
||||||
|
** findLockInfo(). If this is the case, it is quite safe to close
|
||||||
|
** handle h - as it is guaranteed that no posix locks will be released
|
||||||
|
** by doing so.
|
||||||
|
**
|
||||||
|
** If scenario (a) caused the error then things are not so safe. The
|
||||||
|
** implicit assumption here is that if fstat() fails, things are in
|
||||||
|
** such bad shape that dropping a lock or two doesn't matter much.
|
||||||
|
*/
|
||||||
|
close(h);
|
||||||
|
h = -1;
|
||||||
|
}
|
||||||
unixLeaveMutex();
|
unixLeaveMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3525,9 +3536,9 @@ static int fillInUnixFile(
|
|||||||
if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
|
if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
|
||||||
char *zSemName = pNew->pOpen->aSemName;
|
char *zSemName = pNew->pOpen->aSemName;
|
||||||
int n;
|
int n;
|
||||||
sqlite3_snprintf(MAX_PATHNAME, zSemName, "%s.sem",
|
sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem",
|
||||||
pNew->pId->zCanonicalName);
|
pNew->pId->zCanonicalName);
|
||||||
for( n=0; zSemName[n]; n++ )
|
for( n=1; zSemName[n]; n++ )
|
||||||
if( zSemName[n]=='/' ) zSemName[n] = '_';
|
if( zSemName[n]=='/' ) zSemName[n] = '_';
|
||||||
pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
|
pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
|
||||||
if( pNew->pOpen->pSem == SEM_FAILED ){
|
if( pNew->pOpen->pSem == SEM_FAILED ){
|
||||||
@@ -3549,7 +3560,7 @@ static int fillInUnixFile(
|
|||||||
#endif
|
#endif
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
|
if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
|
||||||
close(h);
|
if( h>=0 ) close(h);
|
||||||
}else{
|
}else{
|
||||||
pNew->pMethod = pLockingStyle;
|
pNew->pMethod = pLockingStyle;
|
||||||
OpenCounter(+1);
|
OpenCounter(+1);
|
||||||
@@ -3674,8 +3685,15 @@ static int proxyTransformUnixFile(unixFile*, const char*);
|
|||||||
** If a suitable file descriptor is found, then it is returned. If no
|
** If a suitable file descriptor is found, then it is returned. If no
|
||||||
** such file descriptor is located, -1 is returned.
|
** such file descriptor is located, -1 is returned.
|
||||||
*/
|
*/
|
||||||
static int findReusableFd(const char *zPath, int flags){
|
static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
|
||||||
int fd = -1; /* Return value */
|
UnixUnusedFd *pUnused = 0;
|
||||||
|
|
||||||
|
/* Do not search for an unused file descriptor on vxworks. Not because
|
||||||
|
** vxworks would not benefit from the change (it might, we're not sure),
|
||||||
|
** but because no way to test it is currently available. It is better
|
||||||
|
** not to risk breaking vxworks support for the sake of such an obscure
|
||||||
|
** feature. */
|
||||||
|
#if !OS_VXWORKS
|
||||||
struct stat sStat; /* Results of stat() call */
|
struct stat sStat; /* Results of stat() call */
|
||||||
|
|
||||||
/* A stat() call may fail for various reasons. If this happens, it is
|
/* A stat() call may fail for various reasons. If this happens, it is
|
||||||
@@ -3687,28 +3705,25 @@ static int findReusableFd(const char *zPath, int flags){
|
|||||||
** Even if a subsequent open() call does succeed, the consequences of
|
** Even if a subsequent open() call does succeed, the consequences of
|
||||||
** not searching for a resusable file descriptor are not dire. */
|
** not searching for a resusable file descriptor are not dire. */
|
||||||
if( 0==stat(zPath, &sStat) ){
|
if( 0==stat(zPath, &sStat) ){
|
||||||
struct unixOpenCnt *p;
|
struct unixOpenCnt *pO;
|
||||||
struct unixFileId id;
|
struct unixFileId id;
|
||||||
id.dev = sStat.st_dev;
|
id.dev = sStat.st_dev;
|
||||||
id.ino = sStat.st_ino;
|
id.ino = sStat.st_ino;
|
||||||
|
|
||||||
unixEnterMutex();
|
unixEnterMutex();
|
||||||
for(p=openList; p&& memcmp(&id, &p->fileId, sizeof(id)); p=p->pNext);
|
for(pO=openList; pO && memcmp(&id, &pO->fileId, sizeof(id)); pO=pO->pNext);
|
||||||
if( p && p->aPending ){
|
if( pO ){
|
||||||
int i;
|
UnixUnusedFd **pp;
|
||||||
struct PendingClose *aPending = p->aPending;
|
for(pp=&pO->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
|
||||||
for(i=0; i<p->nPending; i++){
|
pUnused = *pp;
|
||||||
if( aPending[i].fd>=0 && flags==aPending[i].flags ){
|
if( pUnused ){
|
||||||
fd = aPending[i].fd;
|
*pp = pUnused->pNext;
|
||||||
aPending[i].fd = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unixLeaveMutex();
|
unixLeaveMutex();
|
||||||
}
|
}
|
||||||
|
#endif /* if !OS_VXWORKS */
|
||||||
return fd;
|
return pUnused;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3796,14 +3811,17 @@ static int unixOpen(
|
|||||||
memset(p, 0, sizeof(unixFile));
|
memset(p, 0, sizeof(unixFile));
|
||||||
|
|
||||||
if( eType==SQLITE_OPEN_MAIN_DB ){
|
if( eType==SQLITE_OPEN_MAIN_DB ){
|
||||||
/* Try to find an unused file descriptor to reuse. This is not done
|
UnixUnusedFd *pUnused;
|
||||||
** for vxworks. Not because vxworks would not benefit from the change
|
pUnused = findReusableFd(zName, flags);
|
||||||
** (it might, we're not sure), but because no way to test it is
|
if( pUnused ){
|
||||||
** currently available. It is better not to risk breaking vxworks for
|
fd = pUnused->fd;
|
||||||
** the sake of such an obscure feature. */
|
}else{
|
||||||
#if !OS_VXWORKS
|
pUnused = sqlite3_malloc(sizeof(*pUnused));
|
||||||
fd = findReusableFd(zName, flags);
|
if( !pUnused ){
|
||||||
#endif
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->pUnused = pUnused;
|
||||||
}else if( !zName ){
|
}else if( !zName ){
|
||||||
/* If zName is NULL, the upper layer is requesting a temp file. */
|
/* If zName is NULL, the upper layer is requesting a temp file. */
|
||||||
assert(isDelete && !isOpenDirectory);
|
assert(isDelete && !isOpenDirectory);
|
||||||
@@ -3825,24 +3843,32 @@ static int unixOpen(
|
|||||||
openFlags |= (O_LARGEFILE|O_BINARY);
|
openFlags |= (O_LARGEFILE|O_BINARY);
|
||||||
|
|
||||||
if( fd<0 ){
|
if( fd<0 ){
|
||||||
fd = open(zName, openFlags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
|
mode_t openMode = (isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
|
||||||
|
fd = open(zName, openFlags, openMode);
|
||||||
OSTRACE4("OPENX %-3d %s 0%o\n", fd, zName, openFlags);
|
OSTRACE4("OPENX %-3d %s 0%o\n", fd, zName, openFlags);
|
||||||
if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
|
if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
|
||||||
/* Failed to open the file for read/write access. Try read-only. */
|
/* Failed to open the file for read/write access. Try read-only. */
|
||||||
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
||||||
|
openFlags &= ~(O_RDWR|O_CREAT);
|
||||||
flags |= SQLITE_OPEN_READONLY;
|
flags |= SQLITE_OPEN_READONLY;
|
||||||
return unixOpen(pVfs, zPath, pFile, flags, pOutFlags);
|
openFlags |= O_RDONLY;
|
||||||
|
fd = open(zName, openFlags, openMode);
|
||||||
}
|
}
|
||||||
if( fd<0 ){
|
if( fd<0 ){
|
||||||
return SQLITE_CANTOPEN;
|
rc = SQLITE_CANTOPEN;
|
||||||
|
goto open_finished;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert( fd>=0 );
|
assert( fd>=0 );
|
||||||
p->flags = flags;
|
|
||||||
if( pOutFlags ){
|
if( pOutFlags ){
|
||||||
*pOutFlags = flags;
|
*pOutFlags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( p->pUnused ){
|
||||||
|
p->pUnused->fd = fd;
|
||||||
|
p->pUnused->flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
if( isDelete ){
|
if( isDelete ){
|
||||||
#if OS_VXWORKS
|
#if OS_VXWORKS
|
||||||
zPath = zName;
|
zPath = zName;
|
||||||
@@ -3861,11 +3887,11 @@ static int unixOpen(
|
|||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
/* It is safe to close fd at this point, because it is guaranteed not
|
/* It is safe to close fd at this point, because it is guaranteed not
|
||||||
** to be open on a database file. If it were open on a database file,
|
** to be open on a database file. If it were open on a database file,
|
||||||
** it would not be safe to close as this would cause any locks held
|
** it would not be safe to close as this would release any locks held
|
||||||
** on the file by this process to be released. */
|
** on the file by this process. */
|
||||||
assert( eType!=SQLITE_OPEN_MAIN_DB );
|
assert( eType!=SQLITE_OPEN_MAIN_DB );
|
||||||
close(fd); /* silently leak if fail, already in error */
|
close(fd); /* silently leak if fail, already in error */
|
||||||
return rc;
|
goto open_finished;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3876,7 +3902,7 @@ static int unixOpen(
|
|||||||
noLock = eType!=SQLITE_OPEN_MAIN_DB;
|
noLock = eType!=SQLITE_OPEN_MAIN_DB;
|
||||||
|
|
||||||
#if SQLITE_PREFER_PROXY_LOCKING
|
#if SQLITE_PREFER_PROXY_LOCKING
|
||||||
if( zPath!=NULL && !noLock ){
|
if( zPath!=NULL && !noLock && pVfs->xOpen ){
|
||||||
char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
|
char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
|
||||||
int useProxy = 0;
|
int useProxy = 0;
|
||||||
|
|
||||||
@@ -3887,10 +3913,20 @@ static int unixOpen(
|
|||||||
}else{
|
}else{
|
||||||
struct statfs fsInfo;
|
struct statfs fsInfo;
|
||||||
if( statfs(zPath, &fsInfo) == -1 ){
|
if( statfs(zPath, &fsInfo) == -1 ){
|
||||||
((unixFile*)pFile)->lastErrno = errno;
|
/* In theory, the close(fd) call is sub-optimal. If the file opened
|
||||||
if( dirfd>=0 ) close(dirfd); /* silently leak if fail, in error */
|
** with fd is a database file, and there are other connections open
|
||||||
|
** on that file that are currently holding advisory locks on it,
|
||||||
|
** then the call to close() will cancel those locks. In practice,
|
||||||
|
** we're assuming that statfs() doesn't fail very often. At least
|
||||||
|
** not while other file descriptors opened by the same process on
|
||||||
|
** the same file are working. */
|
||||||
|
p->lastErrno = errno;
|
||||||
|
if( dirfd>=0 ){
|
||||||
|
close(dirfd); /* silently leak if fail, in error */
|
||||||
|
}
|
||||||
close(fd); /* silently leak if fail, in error */
|
close(fd); /* silently leak if fail, in error */
|
||||||
return SQLITE_IOERR_ACCESS;
|
rc = SQLITE_IOERR_ACCESS;
|
||||||
|
goto open_finished;
|
||||||
}
|
}
|
||||||
useProxy = !(fsInfo.f_flags&MNT_LOCAL);
|
useProxy = !(fsInfo.f_flags&MNT_LOCAL);
|
||||||
}
|
}
|
||||||
@@ -3899,13 +3935,19 @@ static int unixOpen(
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
|
rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
|
||||||
}
|
}
|
||||||
return rc;
|
goto open_finished;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
|
rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
|
||||||
|
open_finished:
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
sqlite3_free(p->pUnused);
|
||||||
}
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Delete the file at zPath. If the dirSync argument is true, fsync()
|
** Delete the file at zPath. If the dirSync argument is true, fsync()
|
||||||
@@ -4575,33 +4617,43 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
|
|||||||
** but also for freeing the memory associated with the file descriptor.
|
** but also for freeing the memory associated with the file descriptor.
|
||||||
*/
|
*/
|
||||||
static int proxyCreateUnixFile(const char *path, unixFile **ppFile) {
|
static int proxyCreateUnixFile(const char *path, unixFile **ppFile) {
|
||||||
int fd;
|
|
||||||
int dirfd = -1;
|
|
||||||
unixFile *pNew;
|
unixFile *pNew;
|
||||||
|
int flags = SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
sqlite3_vfs dummyVfs;
|
sqlite3_vfs dummyVfs;
|
||||||
|
|
||||||
fd = open(path, O_RDWR | O_CREAT, SQLITE_DEFAULT_FILE_PERMISSIONS);
|
|
||||||
if( fd<0 ){
|
|
||||||
return SQLITE_CANTOPEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
pNew = (unixFile *)sqlite3_malloc(sizeof(unixFile));
|
pNew = (unixFile *)sqlite3_malloc(sizeof(unixFile));
|
||||||
if( pNew==NULL ){
|
if( !pNew ){
|
||||||
rc = SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
goto end_create_proxy;
|
|
||||||
}
|
}
|
||||||
memset(pNew, 0, sizeof(unixFile));
|
memset(pNew, 0, sizeof(unixFile));
|
||||||
|
|
||||||
|
/* Call unixOpen() to open the proxy file. The flags passed to unixOpen()
|
||||||
|
** suggest that the file being opened is a "main database". This is
|
||||||
|
** necessary as other file types do not necessarily support locking. It
|
||||||
|
** is better to use unixOpen() instead of opening the file directly with
|
||||||
|
** open(), as unixOpen() sets up the various mechanisms required to
|
||||||
|
** make sure a call to close() does not cause the system to discard
|
||||||
|
** POSIX locks prematurely.
|
||||||
|
**
|
||||||
|
** It is important that the xOpen member of the VFS object passed to
|
||||||
|
** unixOpen() is NULL. This tells unixOpen() may try to open a proxy-file
|
||||||
|
** for the proxy-file (creating a potential infinite loop).
|
||||||
|
*/
|
||||||
dummyVfs.pAppData = (void*)&autolockIoFinder;
|
dummyVfs.pAppData = (void*)&autolockIoFinder;
|
||||||
rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0);
|
dummyVfs.xOpen = 0;
|
||||||
if( rc==SQLITE_OK ){
|
rc = unixOpen(&dummyVfs, path, (sqlite3_file *)pNew, flags, &flags);
|
||||||
*ppFile = pNew;
|
if( rc==SQLITE_OK && (flags&SQLITE_OPEN_READONLY) ){
|
||||||
return SQLITE_OK;
|
pNew->pMethod->xClose((sqlite3_file *)pNew);
|
||||||
|
rc = SQLITE_CANTOPEN;
|
||||||
}
|
}
|
||||||
end_create_proxy:
|
|
||||||
close(fd); /* silently leak fd if error, we're already in error */
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3_free(pNew);
|
sqlite3_free(pNew);
|
||||||
|
pNew = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppFile = pNew;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2500,7 +2500,8 @@ typedef struct sqlite3_context sqlite3_context;
|
|||||||
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
|
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
|
||||||
**
|
**
|
||||||
** In the SQL strings input to [sqlite3_prepare_v2()] and its variants,
|
** In the SQL strings input to [sqlite3_prepare_v2()] and its variants,
|
||||||
** literals may be replaced by a [parameter] in one of these forms:
|
** literals may be replaced by a [parameter] that matches one of following
|
||||||
|
** templates:
|
||||||
**
|
**
|
||||||
** <ul>
|
** <ul>
|
||||||
** <li> ?
|
** <li> ?
|
||||||
@@ -2510,8 +2511,8 @@ typedef struct sqlite3_context sqlite3_context;
|
|||||||
** <li> $VVV
|
** <li> $VVV
|
||||||
** </ul>
|
** </ul>
|
||||||
**
|
**
|
||||||
** In the parameter forms shown above NNN is an integer literal,
|
** In the templates above, NNN represents an integer literal,
|
||||||
** and VVV is an alpha-numeric parameter name. The values of these
|
** and VVV represents an alphanumeric identifer. The values of these
|
||||||
** parameters (also called "host parameter names" or "SQL parameters")
|
** parameters (also called "host parameter names" or "SQL parameters")
|
||||||
** can be set using the sqlite3_bind_*() routines defined here.
|
** can be set using the sqlite3_bind_*() routines defined here.
|
||||||
**
|
**
|
||||||
@@ -5250,6 +5251,7 @@ typedef struct sqlite3_pcache sqlite3_pcache;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Application Defined Page Cache.
|
** CAPI3REF: Application Defined Page Cache.
|
||||||
|
** KEYWORDS: {page cache}
|
||||||
** EXPERIMENTAL
|
** EXPERIMENTAL
|
||||||
**
|
**
|
||||||
** The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
|
** The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
|
||||||
@@ -5259,12 +5261,14 @@ typedef struct sqlite3_pcache sqlite3_pcache;
|
|||||||
** from, or ready to be written to, the database file. By implementing a
|
** from, or ready to be written to, the database file. By implementing a
|
||||||
** custom page cache using this API, an application can control more
|
** custom page cache using this API, an application can control more
|
||||||
** precisely the amount of memory consumed by SQLite, the way in which
|
** precisely the amount of memory consumed by SQLite, the way in which
|
||||||
** said memory is allocated and released, and the policies used to
|
** that memory is allocated and released, and the policies used to
|
||||||
** determine exactly which parts of a database file are cached and for
|
** determine exactly which parts of a database file are cached and for
|
||||||
** how long.
|
** how long.
|
||||||
**
|
**
|
||||||
** The contents of the structure are copied to an internal buffer by SQLite
|
** The contents of the sqlite3_pcache_methods structure are copied to an
|
||||||
** within the call to [sqlite3_config].
|
** internal buffer by SQLite within the call to [sqlite3_config]. Hence
|
||||||
|
** the application may discard the parameter after the call to
|
||||||
|
** [sqlite3_config()] returns.
|
||||||
**
|
**
|
||||||
** The xInit() method is called once for each call to [sqlite3_initialize()]
|
** The xInit() method is called once for each call to [sqlite3_initialize()]
|
||||||
** (usually only once during the lifetime of the process). It is passed
|
** (usually only once during the lifetime of the process). It is passed
|
||||||
@@ -5285,71 +5289,71 @@ typedef struct sqlite3_pcache sqlite3_pcache;
|
|||||||
** SQLite will never invoke xInit() more than once without an intervening
|
** SQLite will never invoke xInit() more than once without an intervening
|
||||||
** call to xShutdown().
|
** call to xShutdown().
|
||||||
**
|
**
|
||||||
** The xCreate() method is used to construct a new cache instance. The
|
** The xCreate() method is used to construct a new cache instance. SQLite
|
||||||
|
** will typically create one cache instance for each open database file,
|
||||||
|
** though this is not guaranteed. The
|
||||||
** first parameter, szPage, is the size in bytes of the pages that must
|
** first parameter, szPage, is the size in bytes of the pages that must
|
||||||
** be allocated by the cache. szPage will not be a power of two. The
|
** be allocated by the cache. szPage will not be a power of two. szPage
|
||||||
** second argument, bPurgeable, is true if the cache being created will
|
** will the page size of the database file that is to be cached plus an
|
||||||
** be used to cache database pages read from a file stored on disk, or
|
** increment (here called "R") of about 100 or 200. SQLite will use the
|
||||||
|
** extra R bytes on each page to store metadata about the underlying
|
||||||
|
** database page on disk. The value of R depends
|
||||||
|
** on the SQLite version, the target platform, and how SQLite was compiled.
|
||||||
|
** R is constant for a particular build of SQLite. The second argument to
|
||||||
|
** xCreate(), bPurgeable, is true if the cache being created will
|
||||||
|
** be used to cache database pages of a file stored on disk, or
|
||||||
** false if it is used for an in-memory database. The cache implementation
|
** false if it is used for an in-memory database. The cache implementation
|
||||||
** does not have to do anything special based on the value of bPurgeable,
|
** does not have to do anything special based with the value of bPurgeable;
|
||||||
** it is purely advisory.
|
** it is purely advisory. On a cache where bPurgeable is false, SQLite will
|
||||||
|
** never invoke xUnpin() except to deliberately delete a page.
|
||||||
|
** In other words, a cache created with bPurgeable set to false will
|
||||||
|
** never contain any unpinned pages.
|
||||||
**
|
**
|
||||||
** The xCachesize() method may be called at any time by SQLite to set the
|
** The xCachesize() method may be called at any time by SQLite to set the
|
||||||
** suggested maximum cache-size (number of pages stored by) the cache
|
** suggested maximum cache-size (number of pages stored by) the cache
|
||||||
** instance passed as the first argument. This is the value configured using
|
** instance passed as the first argument. This is the value configured using
|
||||||
** the SQLite "[PRAGMA cache_size]" command. As with the bPurgeable parameter,
|
** the SQLite "[PRAGMA cache_size]" command. As with the bPurgeable parameter,
|
||||||
** the implementation is not required to do anything special with this
|
** the implementation is not required to do anything with this
|
||||||
** value, it is advisory only.
|
** value; it is advisory only.
|
||||||
**
|
**
|
||||||
** The xPagecount() method should return the number of pages currently
|
** The xPagecount() method should return the number of pages currently
|
||||||
** stored in the cache supplied as an argument.
|
** stored in the cache.
|
||||||
**
|
**
|
||||||
** The xFetch() method is used to fetch a page and return a pointer to it.
|
** The xFetch() method is used to fetch a page and return a pointer to it.
|
||||||
** A 'page', in this context, is a buffer of szPage bytes aligned at an
|
** A 'page', in this context, is a buffer of szPage bytes aligned at an
|
||||||
** 8-byte boundary. The page to be fetched is determined by the key. The
|
** 8-byte boundary. The page to be fetched is determined by the key. The
|
||||||
** mimimum key value is 1. After it has been retrieved using xFetch, the page
|
** mimimum key value is 1. After it has been retrieved using xFetch, the page
|
||||||
** is considered to be pinned.
|
** is considered to be "pinned".
|
||||||
**
|
**
|
||||||
** If the requested page is already in the page cache, then a pointer to
|
** If the requested page is already in the page cache, then the page cache
|
||||||
** the cached buffer should be returned with its contents intact. If the
|
** implementation must return a pointer to the page buffer with its content
|
||||||
** page is not already in the cache, then the expected behaviour of the
|
** intact. If the requested page is not already in the cache, then the
|
||||||
** cache is determined by the value of the createFlag parameter passed
|
** behavior of the cache implementation is determined by the value of the
|
||||||
** to xFetch, according to the following table:
|
** createFlag parameter passed to xFetch, according to the following table:
|
||||||
**
|
**
|
||||||
** <table border=1 width=85% align=center>
|
** <table border=1 width=85% align=center>
|
||||||
** <tr><th>createFlag<th>Expected Behaviour
|
** <tr><th> createFlag <th> Behaviour when page is not already in cache
|
||||||
** <tr><td>0<td>NULL should be returned. No new cache entry is created.
|
** <tr><td> 0 <td> Do not allocate a new page. Return NULL.
|
||||||
** <tr><td>1<td>If createFlag is set to 1, this indicates that
|
** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
|
||||||
** SQLite is holding pinned pages that can be unpinned
|
** Otherwise return NULL.
|
||||||
** by writing their contents to the database file (a
|
** <tr><td> 2 <td> Make every effort to allocate a new page. Only return
|
||||||
** relatively expensive operation). In this situation the
|
** NULL if allocating a new page is effectively impossible.
|
||||||
** cache implementation has two choices: it can return NULL,
|
|
||||||
** in which case SQLite will attempt to unpin one or more
|
|
||||||
** pages before re-requesting the same page, or it can
|
|
||||||
** allocate a new page and return a pointer to it. If a new
|
|
||||||
** page is allocated, then the first sizeof(void*) bytes of
|
|
||||||
** it (at least) must be zeroed before it is returned.
|
|
||||||
** <tr><td>2<td>If createFlag is set to 2, then SQLite is not holding any
|
|
||||||
** pinned pages associated with the specific cache passed
|
|
||||||
** as the first argument to xFetch() that can be unpinned. The
|
|
||||||
** cache implementation should attempt to allocate a new
|
|
||||||
** cache entry and return a pointer to it. Again, the first
|
|
||||||
** sizeof(void*) bytes of the page should be zeroed before
|
|
||||||
** it is returned. If the xFetch() method returns NULL when
|
|
||||||
** createFlag==2, SQLite assumes that a memory allocation
|
|
||||||
** failed and returns SQLITE_NOMEM to the user.
|
|
||||||
** </table>
|
** </table>
|
||||||
**
|
**
|
||||||
|
** SQLite will normally invoke xFetch() with a createFlag of 0 or 1. If
|
||||||
|
** a call to xFetch() with createFlag==1 returns NULL, then SQLite will
|
||||||
|
** attempt to unpin one or more cache pages by spilling the content of
|
||||||
|
** pinned pages to disk and synching the operating system disk cache. After
|
||||||
|
** attempting to unpin pages, the xFetch() method will be invoked again with
|
||||||
|
** a createFlag of 2.
|
||||||
|
**
|
||||||
** xUnpin() is called by SQLite with a pointer to a currently pinned page
|
** xUnpin() is called by SQLite with a pointer to a currently pinned page
|
||||||
** as its second argument. If the third parameter, discard, is non-zero,
|
** as its second argument. If the third parameter, discard, is non-zero,
|
||||||
** then the page should be evicted from the cache. In this case SQLite
|
** then the page should be evicted from the cache. In this case SQLite
|
||||||
** assumes that the next time the page is retrieved from the cache using
|
** assumes that the next time the page is retrieved from the cache using
|
||||||
** the xFetch() method, it will be zeroed. If the discard parameter is
|
** the xFetch() method, it will be zeroed. If the discard parameter is
|
||||||
** zero, then the page is considered to be unpinned. The cache implementation
|
** zero, then the page is considered to be unpinned. The cache implementation
|
||||||
** may choose to reclaim (free or recycle) unpinned pages at any time.
|
** may choose to evict unpinned pages at any time.
|
||||||
** SQLite assumes that next time the page is retrieved from the cache
|
|
||||||
** it will either be zeroed, or contain the same data that it did when it
|
|
||||||
** was unpinned.
|
|
||||||
**
|
**
|
||||||
** The cache is not required to perform any reference counting. A single
|
** The cache is not required to perform any reference counting. A single
|
||||||
** call to xUnpin() unpins the page regardless of the number of prior calls
|
** call to xUnpin() unpins the page regardless of the number of prior calls
|
||||||
|
|||||||
@@ -779,6 +779,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
|||||||
sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
|
sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
|
||||||
}else if( pMem->flags & MEM_Real ){
|
}else if( pMem->flags & MEM_Real ){
|
||||||
sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r);
|
sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r);
|
||||||
|
}else{
|
||||||
|
assert( pMem->flags & MEM_Blob );
|
||||||
|
zP4 = "(blob)";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2728,9 +2731,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
|
|||||||
assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
|
assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
|
||||||
|
|
||||||
/* Read in the complete content of the index entry */
|
/* Read in the complete content of the index entry */
|
||||||
m.flags = 0;
|
memset(&m, 0, sizeof(m));
|
||||||
m.db = db;
|
|
||||||
m.zMalloc = 0;
|
|
||||||
rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m);
|
rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
return rc;
|
return rc;
|
||||||
@@ -2808,9 +2809,7 @@ int sqlite3VdbeIdxKeyCompare(
|
|||||||
*res = 0;
|
*res = 0;
|
||||||
return SQLITE_CORRUPT;
|
return SQLITE_CORRUPT;
|
||||||
}
|
}
|
||||||
m.db = 0;
|
memset(&m, 0, sizeof(m));
|
||||||
m.flags = 0;
|
|
||||||
m.zMalloc = 0;
|
|
||||||
rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m);
|
rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
18
src/where.c
18
src/where.c
@@ -1974,6 +1974,7 @@ static int whereRangeRegion(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert( i>=0 && i<=SQLITE_INDEX_SAMPLES );
|
||||||
*piRegion = i;
|
*piRegion = i;
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@@ -2038,8 +2039,8 @@ static int whereRangeScanEst(
|
|||||||
|
|
||||||
if( nEq==0 && p->aSample ){
|
if( nEq==0 && p->aSample ){
|
||||||
int iEst;
|
int iEst;
|
||||||
int iUpper;
|
int iLower = 0;
|
||||||
int iLower;
|
int iUpper = SQLITE_INDEX_SAMPLES;
|
||||||
u8 aff = p->pTable->aCol[0].affinity;
|
u8 aff = p->pTable->aCol[0].affinity;
|
||||||
|
|
||||||
if( pLower ){
|
if( pLower ){
|
||||||
@@ -2057,24 +2058,21 @@ static int whereRangeScanEst(
|
|||||||
goto range_est_fallback;
|
goto range_est_fallback;
|
||||||
}else if( pLowerVal==0 ){
|
}else if( pLowerVal==0 ){
|
||||||
rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper);
|
rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper);
|
||||||
iLower = pLower ? iUpper/2 : 0;
|
if( pLower ) iLower = iUpper/2;
|
||||||
}else if( pUpperVal==0 ){
|
}else if( pUpperVal==0 ){
|
||||||
rc = whereRangeRegion(pParse, p, pLowerVal, &iLower);
|
rc = whereRangeRegion(pParse, p, pLowerVal, &iLower);
|
||||||
iUpper = pUpper ? (iLower + SQLITE_INDEX_SAMPLES + 1)/2
|
if( pUpper ) iUpper = (iLower + SQLITE_INDEX_SAMPLES + 1)/2;
|
||||||
: SQLITE_INDEX_SAMPLES;
|
|
||||||
}else{
|
}else{
|
||||||
rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper);
|
rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = whereRangeRegion(pParse, p, pLowerVal, &iLower);
|
rc = whereRangeRegion(pParse, p, pLowerVal, &iLower);
|
||||||
}else{
|
|
||||||
iLower = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iEst = iUpper - iLower;
|
iEst = iUpper - iLower;
|
||||||
if( iEst>SQLITE_INDEX_SAMPLES ){
|
testcase( iEst==SQLITE_INDEX_SAMPLES );
|
||||||
iEst = SQLITE_INDEX_SAMPLES;
|
assert( iEst<=SQLITE_INDEX_SAMPLES );
|
||||||
}else if( iEst<1 ){
|
if( iEst<1 ){
|
||||||
iEst = 1;
|
iEst = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ do_test tkt4018-1.1 {
|
|||||||
} {}
|
} {}
|
||||||
|
|
||||||
# The database is locked by connection [db]. Open and close a second
|
# The database is locked by connection [db]. Open and close a second
|
||||||
# connection to test.db 20000 times. If file-descriptors are not being
|
# connection to test.db 10000 times. If file-descriptors are not being
|
||||||
# reused, then the process will quickly exceed its maximum number of
|
# reused, then the process will quickly exceed its maximum number of
|
||||||
# file descriptors (1024 by default on linux).
|
# file descriptors (1024 by default on linux).
|
||||||
do_test tkt4018-1.2 {
|
do_test tkt4018-1.2 {
|
||||||
|
|||||||
Reference in New Issue
Block a user