1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Pull the latest trunk changes into the sessions branch, and in particular

the collating-sequence refactorization.

FossilOrigin-Name: 4f6d69ae94671df92b976525f75404c01270fef9
This commit is contained in:
drh
2012-12-08 23:37:22 +00:00
50 changed files with 736 additions and 340 deletions

View File

@@ -45,7 +45,7 @@ TCC += @TCL_INCLUDE_SPEC@
# The library that programs using TCL must link against. # The library that programs using TCL must link against.
# #
LIBTCL = @TCL_LIB_SPEC@ @TCL_LIBS@ LIBTCL = @TCL_LIB_SPEC@
# Compiler options needed for programs that use the readline() library. # Compiler options needed for programs that use the readline() library.
# #
@@ -935,7 +935,6 @@ clean:
rm -rf .libs .deps rm -rf .libs .deps
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
rm -f mkkeywordhash$(BEXE) keywordhash.h rm -f mkkeywordhash$(BEXE) keywordhash.h
rm -f $(PUBLISH)
rm -f *.da *.bb *.bbg gmon.out rm -f *.da *.bb *.bbg gmon.out
rm -rf quota2a quota2b quota2c rm -rf quota2a quota2b quota2c
rm -rf tsrc .target_source rm -rf tsrc .target_source

View File

@@ -845,8 +845,8 @@ sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
sqlite3.c: .target_source $(TOP)\tool\mksqlite3c.tcl sqlite3.c: .target_source $(TOP)\tool\mksqlite3c.tcl
$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl $(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl
sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
$(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl $(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
# Rule to build the amalgamation # Rule to build the amalgamation
# #

1
configure vendored
View File

@@ -879,7 +879,6 @@ TARGET_EXEEXT
TCL_VERSION TCL_VERSION
TCL_BIN_DIR TCL_BIN_DIR
TCL_SRC_DIR TCL_SRC_DIR
TCL_LIBS
TCL_INCLUDE_SPEC TCL_INCLUDE_SPEC
TCL_LIB_FILE TCL_LIB_FILE
TCL_LIB_FLAG TCL_LIB_FLAG

View File

@@ -501,7 +501,6 @@ if test "${use_tcl}" = "yes" ; then
AC_SUBST(TCL_VERSION) AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_BIN_DIR)
AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_LIBS)
AC_SUBST(TCL_INCLUDE_SPEC) AC_SUBST(TCL_INCLUDE_SPEC)
AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FILE)

View File

@@ -1,3 +1,10 @@
NOTE (2012-11-29):
The functionality implemented by this extension has been superseded
by WAL-mode. This module is no longer supported or maintained. The
code is retained for historical reference only.
------------------------------------------------------------------------------
Normally, when SQLite writes to a database file, it waits until the write Normally, when SQLite writes to a database file, it waits until the write
operation is finished before returning control to the calling application. operation is finished before returning control to the calling application.
@@ -161,4 +168,3 @@ the database, eliminating the bottleneck.
The functionality required of each of the above functions is described The functionality required of each of the above functions is described
in comments in sqlite3async.c. in comments in sqlite3async.c.

View File

@@ -1510,6 +1510,7 @@ static void asyncWriterThread(void){
case ASYNC_DELETE: case ASYNC_DELETE:
ASYNC_TRACE(("DELETE %s\n", p->zBuf)); ASYNC_TRACE(("DELETE %s\n", p->zBuf));
rc = pVfs->xDelete(pVfs, p->zBuf, (int)p->iOffset); rc = pVfs->xDelete(pVfs, p->zBuf, (int)p->iOffset);
if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
break; break;
case ASYNC_OPENEXCLUSIVE: { case ASYNC_OPENEXCLUSIVE: {

View File

@@ -75,7 +75,7 @@ int sqlite3async_initialize(const char *zParent, int isDefault);
** On win32 platforms, this function also releases the small number of ** On win32 platforms, this function also releases the small number of
** critical section and event objects created by sqlite3async_initialize(). ** critical section and event objects created by sqlite3async_initialize().
*/ */
void sqlite3async_shutdown(); void sqlite3async_shutdown(void);
/* /*
** This function may only be called when the asynchronous IO VFS is ** This function may only be called when the asynchronous IO VFS is
@@ -94,7 +94,7 @@ void sqlite3async_shutdown();
** If multiple simultaneous calls are made to sqlite3async_run() from two ** If multiple simultaneous calls are made to sqlite3async_run() from two
** or more threads, then the calls are serialized internally. ** or more threads, then the calls are serialized internally.
*/ */
void sqlite3async_run(); void sqlite3async_run(void);
/* /*
** This function may only be called when the asynchronous IO VFS is ** This function may only be called when the asynchronous IO VFS is

View File

@@ -5253,7 +5253,7 @@ int sqlite3Fts3UpdateMethod(
int rc = SQLITE_OK; /* Return Code */ int rc = SQLITE_OK; /* Return Code */
int isRemove = 0; /* True for an UPDATE or DELETE */ int isRemove = 0; /* True for an UPDATE or DELETE */
u32 *aSzIns = 0; /* Sizes of inserted documents */ u32 *aSzIns = 0; /* Sizes of inserted documents */
u32 *aSzDel; /* Sizes of deleted documents */ u32 *aSzDel = 0; /* Sizes of deleted documents */
int nChng = 0; /* Net change in number of documents */ int nChng = 0; /* Net change in number of documents */
int bInsertDone = 0; int bInsertDone = 0;

106
manifest
View File

@@ -1,9 +1,9 @@
C Update\sthe\ssessions\sbranch\sto\sinclude\sthe\sSQLLOG\senhancement,\sthe\nSQLITE_IOERR_DELETE_NOENT\sfix,\sand\sa\sfix\sfor\sthe\snumber-of-documents\nbug\sin\sFTS4. C Pull\sthe\slatest\strunk\schanges\sinto\sthe\ssessions\sbranch,\sand\sin\sparticular\nthe\scollating-sequence\srefactorization.
D 2012-11-27T21:56:28.635 D 2012-12-08T23:37:22.043
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 82c41c0ed4cc94dd3cc7d498575b84c57c2c2384 F Makefile.in 690d441a758cbffd13e814dc2724a721a6ebd400
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 1aba45c2d159c2beb62486e4eaa6e2c96c56dd46 F Makefile.msc 26fd6e94ef8ed7d8b8c84b96b8347c52485f6d83
F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION edab4af5a4623f8198833ea481ce98ab53750a8d F VERSION edab4af5a4623f8198833ea481ce98ab53750a8d
@@ -15,16 +15,16 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 2f40e28f141c324333498977b01f744fe189462e x F configure 20ac96f94269b3e2417b91fac63a9db0eb0a9b15 x
F configure.ac 6e909664785b8184db2179013cd9d574f96ca3a3 F configure.ac 81c43d151d0b0e406be056394cc9ff4cb3fd0444
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1 F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
F ext/async/README.txt 0c541f418b14b415212264cbaaf51c924ec62e5b F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
F ext/async/sqlite3async.c 733a9f21b1066f44ff07b9c0da973b1e483d1e0c F ext/async/sqlite3async.c b5a3e30f538a9ffe81538b3063b4d5963f9bb422
F ext/async/sqlite3async.h a21e1252deb14a2c211f0e165c4b9122a8f1f344 F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
F ext/fts1/ft_hash.h 1a35e654a235c2c662d3ca0dfc3138ad60b8b7d5 F ext/fts1/ft_hash.h 1a35e654a235c2c662d3ca0dfc3138ad60b8b7d5
@@ -72,7 +72,7 @@ F ext/fts3/fts3_tokenizer.h 66dec98e365854b6cd2d54f1a96bb6d428fc5a68
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c 49e36e6ba59f79e6bd6a8bfe434570fe48d20559 F ext/fts3/fts3_unicode.c 49e36e6ba59f79e6bd6a8bfe434570fe48d20559
F ext/fts3/fts3_unicode2.c a863f05f758af36777dffc2facc898bc73fec896 F ext/fts3/fts3_unicode2.c a863f05f758af36777dffc2facc898bc73fec896
F ext/fts3/fts3_write.c a432433a706bd065e8bb0f8b3b33ce7cf9d7f21d F ext/fts3/fts3_write.c c2166f7148a4ad8bcdad99a99d647b1091744e6b
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197 F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
@@ -128,7 +128,7 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168 F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168
F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410 F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410
F src/attach.c 34c15ecd686e58f08e5bb1389e28a0b65c2c83db F src/attach.c ea5247f240e2c08afd608e9beb380814b86655e1
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c cab40f2c1fe79d6eb93d3b4086c78c41ad2fa5d0 F src/backup.c cab40f2c1fe79d6eb93d3b4086c78c41ad2fa5d0
F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1 F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1
@@ -136,22 +136,22 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c eccee944cb2221e919d7a855e5928d8643194b14 F src/btree.c eccee944cb2221e919d7a855e5928d8643194b14
F src/btree.h 3ad7964d6c5b1c7bff569aab6adfa075f8bf06cd F src/btree.h 3ad7964d6c5b1c7bff569aab6adfa075f8bf06cd
F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621 F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
F src/build.c f35dac52924a6e8e6346a90f0c195a84e28b6f21 F src/build.c f4f86c07002c6f3ee96c1e34e0e993a962ef2c73
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
F src/delete.c 9bc9463952bdc9fc43111b1f9c83a0af9b8e2239 F src/delete.c 9bc9463952bdc9fc43111b1f9c83a0af9b8e2239
F src/expr.c 3b25a95f3d309403940ba4a3212f197b8b6251d5 F src/expr.c 0e41d66d868b37dbc0e041c342e0036fad27e705
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af F src/fkey.c dcb7c37a4bf526ded7b24a01a60fe071bcd160a2
F src/func.c 1755cafdb8f2a291681f1ea55e0215518ebd6e52 F src/func.c 8147799b048065a1590805be464d05b4913e652c
F src/global.c e59ecd2c553ad0d4bfbc84ca71231336f8993a7a F src/global.c e59ecd2c553ad0d4bfbc84ca71231336f8993a7a
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 6273647b67e27e3f81b7d1fd144307ea726841d0 F src/insert.c 36c17b9b97a9287aa8561f138d893ddf2b25d0b2
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/journal.c eb7b9f5e783266521bcd9b2b93d419a219411f71
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
@@ -172,11 +172,11 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c
F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57 F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c b75d9b0876ad3fde151843ad389b4c3dd727c662 F src/os_unix.c ad459bb62eb6f3f6aae26d97b1a28fbac7bf0260
F src/os_win.c 6e55b48f793d0c0d0e086d3f1482a0882530eeeb F src/os_win.c ce1f5db8a7bb4d6f2092b1b2cb9631bec54a6320
F src/pager.c ed53fe75a269c1d67645fe079ea0f3f0ce6492d5 F src/pager.c 4092c907222cfd451c74fe6bd2fd64b342f7190f
F src/pager.h 1109a06578ec5574dc2c74cf8d9f69daf36fe3e0 F src/pager.h 1109a06578ec5574dc2c74cf8d9f69daf36fe3e0
F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 F src/parse.y c2b4a6454ad77299b1443e2c483a560a9f16e724
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9 F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9
@@ -184,19 +184,19 @@ F src/pragma.c 015723c48072781d2740e310ab04dc92956b76d1
F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c
F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 7b986a715ac281643309c29257bb58cfae7aa810 F src/resolve.c cdd546d62da7763119ea1fa455a898959e03457f
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 3a8baf4719f9723b4e0b43f2baa60692d0d921f8 F src/select.c e6daa524bbdfa98f4abdb8cb281498f0047d3161
F src/shell.c 24cd0aa74aff73ea08594629faead564c4c2a286 F src/shell.c e392dd1ccbb77cc1d75a8367a89b473c24bea019
F src/sqlite.h.in 36d91c7ca79b9fb35831a0f097f4fcb653819a10 F src/sqlite.h.in 2be63c600ddc118753c6058639b282554d7f759c
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
F src/sqliteInt.h 3a67c14ba5f17c33f2f9c551bb03c4c341de0bd4 F src/sqliteInt.h e08e87a07d3cbbc57423c78f56b334579ef17741
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9 F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 289be7b639406314813219ee7bc043d21f36ab12 F src/tclsqlite.c 289be7b639406314813219ee7bc043d21f36ab12
F src/test1.c 936afc02766403e5debca49a1817a780e116df7e F src/test1.c f62769c989146149590662ab02de4a813813a9c5
F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf
F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d
F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa
@@ -220,7 +220,7 @@ F src/test_intarray.c 07ddcebe4097d400ffca362770f1d883c112387a
F src/test_intarray.h b999bb18d090b8d9d9c49d36ec37ef8f341fe169 F src/test_intarray.h b999bb18d090b8d9d9c49d36ec37ef8f341fe169
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
F src/test_malloc.c 01cd65ae7ae93de9fbf8214d1ee6b4eba4850700 F src/test_malloc.c 6982a357a6a6c24f281b91c89303a5c31075c392
F src/test_multiplex.c ac0fbc1748e5b86a41a1d7a84654fae0d53a881d F src/test_multiplex.c ac0fbc1748e5b86a41a1d7a84654fae0d53a881d
F src/test_multiplex.h 9b63b95f07acedee425fdfe49a47197c9bf5f9d8 F src/test_multiplex.h 9b63b95f07acedee425fdfe49a47197c9bf5f9d8
F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
@@ -233,27 +233,27 @@ F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
F src/test_spellfix.c 76dd8d3111d2f5354c374f71fa23b752bd0b029c F src/test_spellfix.c 76dd8d3111d2f5354c374f71fa23b752bd0b029c
F src/test_sqllog.c 7813b47021a6d4e39bb7b1b328a8893dc59885cb F src/test_sqllog.c 8acb843ddb9928dea8962e31bb09f421a72ffccb
F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935 F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c e286f2173563f2a1747c24bcda6b9d030bf4f4e4 F src/test_thread.c e286f2173563f2a1747c24bcda6b9d030bf4f4e4
F src/test_vfs.c c6260ef238c1142c8f8bd402db02216afd182ae3 F src/test_vfs.c c6260ef238c1142c8f8bd402db02216afd182ae3
F src/test_vfstrace.c f60e12754e65c05386aab59db8d2ae086314138d F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
F src/test_wholenumber.c 3d2b9ed1505c40ad5c5ca2ad16ae7a289d6cc251 F src/test_wholenumber.c 3d2b9ed1505c40ad5c5ca2ad16ae7a289d6cc251
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12 F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
F src/trigger.c 3f258307040173aff383eb23fb74c44fe829078c F src/trigger.c cd95ac64efa60e39faf9b5597443192ff27a22fa
F src/update.c abb0fcabe551dae0a133fd2a4370b5a8c23b1831 F src/update.c abb0fcabe551dae0a133fd2a4370b5a8c23b1831
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455 F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455
F src/vacuum.c 2727bdd08847fcb6b2d2da6d14f018910e8645d3 F src/vacuum.c 2727bdd08847fcb6b2d2da6d14f018910e8645d3
F src/vdbe.c 640a7e140c7dc0465eff7e515252e434ca77286e F src/vdbe.c 85576363e303ffa5dc7d368af4cfd6bfbee96db1
F src/vdbe.h 1223e2548e0970cf96f573ff6b99f804a36ad683 F src/vdbe.h 1223e2548e0970cf96f573ff6b99f804a36ad683
F src/vdbeInt.h 2de43968dc47f1961d5bc76aa3cb68eacf433a7c F src/vdbeInt.h 2de43968dc47f1961d5bc76aa3cb68eacf433a7c
F src/vdbeapi.c 58fdcd56109c05876f69c25d47a138ef370d3647 F src/vdbeapi.c 58fdcd56109c05876f69c25d47a138ef370d3647
F src/vdbeaux.c b8f2a0cb28401b7252bdbaba8988f53691909497 F src/vdbeaux.c 0ce759dca1d1662f45f60a9336bf84b5cd15debf
F src/vdbeblob.c 11248c6362389569764682eb0f59ce910f3cc381 F src/vdbeblob.c 11248c6362389569764682eb0f59ce910f3cc381
F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74 F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
F src/vdbesort.c c61ca318681c0e7267da8be3abfca8469652a7e9 F src/vdbesort.c c61ca318681c0e7267da8be3abfca8469652a7e9
@@ -262,7 +262,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2 F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
F src/where.c 832e33fefbe5ba751c1f5a06e63de98be95e56f2 F src/where.c 53b991af50dab230b319b098bcb90fc7cd82da47
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -302,7 +302,7 @@ F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
F test/backcompat.test ecd841f3a3bfb81518721879cc56a760670e3198 F test/backcompat.test ecd841f3a3bfb81518721879cc56a760670e3198
F test/backup.test c9cdd23a495864b9edf75a9fa66f5cb7e10fcf62 F test/backup.test c9cdd23a495864b9edf75a9fa66f5cb7e10fcf62
F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf
F test/backup4.test 3c3639d28f3cdb4a123694a0a7c5fa7bfe304e2a F test/backup4.test 4d90389daeb781fe718816a4fc836ad1b06791d8
F test/backup_ioerr.test 40d208bc9224b666ee3ed423f49bc9062a36a9d0 F test/backup_ioerr.test 40d208bc9224b666ee3ed423f49bc9062a36a9d0
F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450 F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
@@ -335,7 +335,7 @@ F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/check.test 193f47ed43a8d29aca12b30cd30ceb105fbe710d F test/check.test 193f47ed43a8d29aca12b30cd30ceb105fbe710d
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04 F test/collate1.test fd02c4d8afc71879c4bb952586389961a21fb0ce
F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49 F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49
F test/collate3.test d28d2cfab2c3a3d4628ae4b2b7afc9965daa3b4c F test/collate3.test d28d2cfab2c3a3d4628ae4b2b7afc9965daa3b4c
F test/collate4.test d37682293d3c32223dec2e6afdeaf9de18415248 F test/collate4.test d37682293d3c32223dec2e6afdeaf9de18415248
@@ -388,7 +388,7 @@ F test/descidx1.test 533dcbda614b0463b0ea029527fd27e5a9ab2d66
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test c239558222e5ae357aade535bfe61aaabcb00bbf F test/distinct.test 84da1414b2e6887fffd5ed571311b344c5b082ce
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_createtable.test 0a2465736199cb5e084645a8714ee04299b81721 F test/e_createtable.test 0a2465736199cb5e084645a8714ee04299b81721
F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5 F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5
@@ -418,7 +418,7 @@ F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30 F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d
F test/fallocate.test b5d34437bd7ab01d41b1464b8117aefd4d32160e F test/fallocate.test b5d34437bd7ab01d41b1464b8117aefd4d32160e
F test/filectrl.test f0327bd804d9c7bd048fa7a151c5eab8e27df42b F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
F test/filefmt.test ffa17b5aebc3eb4b1e3be1ccb5ee906ffbd97f6e F test/filefmt.test ffa17b5aebc3eb4b1e3be1ccb5ee906ffbd97f6e
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
F test/fkey2.test 080969fe219b3b082b0e097ac18c6af2e5b0631f F test/fkey2.test 080969fe219b3b082b0e097ac18c6af2e5b0631f
@@ -559,7 +559,7 @@ F test/insert4.test 87f6798f31d60c4e177622fcc3663367e6ecbd90
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
F test/instr.test a34e1d46a9eefb098a7167ef0e730a4a3d82fba0 F test/instr.test a34e1d46a9eefb098a7167ef0e730a4a3d82fba0
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1 F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc
F test/intpkey.test 7af30f6ae852d8d1c2b70e4bf1551946742e92d8 F test/intpkey.test 7af30f6ae852d8d1c2b70e4bf1551946742e92d8
F test/io.test 36d251507d72e92b965fb2f0801c2f0b56335bcf F test/io.test 36d251507d72e92b965fb2f0801c2f0b56335bcf
F test/ioerr.test 40bb2cfcab63fb6aa7424cd97812a84bc16b5fb8 F test/ioerr.test 40bb2cfcab63fb6aa7424cd97812a84bc16b5fb8
@@ -599,7 +599,7 @@ F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2
F test/main.test 39c4bb8a157f57298ed1659d6df89d9f35aaf2c8 F test/main.test 39c4bb8a157f57298ed1659d6df89d9f35aaf2c8
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test bc745155ff4252d4f35ec8316625b0dfe2abc659 F test/malloc.test bc745155ff4252d4f35ec8316625b0dfe2abc659
F test/malloc3.test de8eca0c3e748878845fdca3663ec4b642073caf F test/malloc3.test 3e9eb921c4314acf4fb64230868fdb2e1ce60eea
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261 F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test a577cbbcc1594c7763b9b3515b3633555751c7f0 F test/malloc5.test a577cbbcc1594c7763b9b3515b3633555751c7f0
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151 F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
@@ -718,10 +718,10 @@ F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d
F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9 F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9
F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e
F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d
F test/shared9.test 614a3ca431adc73c857632deb4eff75bcaee40ec F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa
F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf
F test/shell1.test 340125225cc96c7f48d59a869aaf82866e481007 F test/shell1.test b7896eb84028f3bc8300caf1fc796a73728aad0b
F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a
F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59 F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
@@ -745,7 +745,7 @@ F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test be8d477306006ec696bc86757cfb34bec79447ce F test/stat.test be8d477306006ec696bc86757cfb34bec79447ce
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
F test/subquery.test d4aea23ac267463d4aa604bf937c3992347b20f7 F test/subquery.test d4aea23ac267463d4aa604bf937c3992347b20f7
F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd F test/subquery2.test 91e1e364072aeff431d1f9689b15147e421d88c7
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
@@ -759,7 +759,7 @@ F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2 F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2
F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d
F test/tester.tcl ac81733138d2b159f0b7f0379b6509e301f47cd4 F test/tester.tcl ac81733138d2b159f0b7f0379b6509e301f47cd4
F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91 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
F test/thread004.test f51dfc3936184aaf73ee85f315224baad272a87f F test/thread004.test f51dfc3936184aaf73ee85f315224baad272a87f
@@ -843,7 +843,7 @@ F test/tkt2686.test 6ee01c9b9e9c48f6d3a1fdd553b1cc4258f903d6
F test/tkt2767.test 569000d842678f9cf2db7e0d1b27cbc9011381b0 F test/tkt2767.test 569000d842678f9cf2db7e0d1b27cbc9011381b0
F test/tkt2817.test f31839e01f4243cff7399ef654d3af3558cb8d8d F test/tkt2817.test f31839e01f4243cff7399ef654d3af3558cb8d8d
F test/tkt2820.test 39940276b3436d125deb7d8ebeee053e4cf13213 F test/tkt2820.test 39940276b3436d125deb7d8ebeee053e4cf13213
F test/tkt2822.test a2b27a58df62d1b2e712f91dbe42ad3b7e0e77cc F test/tkt2822.test f391776423a7c0d0949edfce375708bfb0f3141e
F test/tkt2832.test a9b0b74a02dca166a04d9e37739c414b10929caa F test/tkt2832.test a9b0b74a02dca166a04d9e37739c414b10929caa
F test/tkt2854.test e432965db29e27e16f539b2ba7f502eb2ccc49af F test/tkt2854.test e432965db29e27e16f539b2ba7f502eb2ccc49af
F test/tkt2920.test a8737380e4ae6424e00c0273dc12775704efbebf F test/tkt2920.test a8737380e4ae6424e00c0273dc12775704efbebf
@@ -912,7 +912,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31 F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31
F test/triggerA.test e0aaba16d3547193d36bbd82a1b0ed75e9c88d40 F test/triggerA.test e0aaba16d3547193d36bbd82a1b0ed75e9c88d40
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
F test/triggerC.test 29173df06f8e91bec2b95ea7048b30d1e1c7b9db F test/triggerC.test a7b4367392c755bc5fd5fff88011753e6b6afe90
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
@@ -931,7 +931,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 7701bb609fe8bf6535514e8b849a309e8f00573b F test/veryquick.test 7701bb609fe8bf6535514e8b849a309e8f00573b
F test/view.test b182a67ec43f490b156b5a710827a341be83dd17 F test/view.test b182a67ec43f490b156b5a710827a341be83dd17
F test/vtab1.test 10fb9e656fe4b318cd82ff1616a340acc01aac4b F test/vtab1.test 36c9935e4be3b6350b31b6b697561b6fc3ab349a
F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d
F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1 F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275 F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
@@ -957,7 +957,7 @@ F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437
F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3 F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
F test/wal8.test b3ee739fe8f7586aaebdc2367f477ebcf3e3b034 F test/wal8.test b3ee739fe8f7586aaebdc2367f477ebcf3e3b034
F test/wal9.test 48c40803faf6849515c81213697e9f3376835981 F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877 F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877
F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434 F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434
@@ -974,7 +974,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1
F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test 41b65069a227a61238c1387b050f029480ca5677 F test/where.test 9714e6f292d70c22e78e1cecb3d896457186b9b7
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554 F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006 F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
@@ -1038,7 +1038,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P 2993ca20207f8dac02f58d01e31d68c84328356a f0843f885ab3337f83fe3b304aab80bb7b5dd0a3 P ba8d08b67021a32fda069c18b7eb93523e6f0d1f 92c9ab56b1c67b9468bec57ab1d2c483a69a2810
R 4a1915adbe009074546a4e2d976a205c R f06c7a4e8d9fd6f22d929caa0d8aff12
U drh U drh
Z 7494d16bf0eedbea369965ccf52a8519 Z 66550b6aeab54597acd3e06f02611eed

View File

@@ -1 +1 @@
ba8d08b67021a32fda069c18b7eb93523e6f0d1f 4f6d69ae94671df92b976525f75404c01270fef9

View File

@@ -471,7 +471,7 @@ int sqlite3FixSrcList(
pFix->zType, pFix->pName, pItem->zDatabase); pFix->zType, pFix->pName, pItem->zDatabase);
return 1; return 1;
} }
sqlite3_free(pItem->zDatabase); sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
pItem->zDatabase = 0; pItem->zDatabase = 0;
pItem->pSchema = pFix->pSchema; pItem->pSchema = pFix->pSchema;
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)

View File

@@ -127,6 +127,7 @@ void sqlite3FinishCoding(Parse *pParse){
sqlite3 *db; sqlite3 *db;
Vdbe *v; Vdbe *v;
assert( pParse->pToplevel==0 );
db = pParse->db; db = pParse->db;
if( db->mallocFailed ) return; if( db->mallocFailed ) return;
if( pParse->nested ) return; if( pParse->nested ) return;
@@ -2690,10 +2691,8 @@ Index *sqlite3CreateIndex(
for(i=0; i<pList->nExpr; i++){ for(i=0; i<pList->nExpr; i++){
Expr *pExpr = pList->a[i].pExpr; Expr *pExpr = pList->a[i].pExpr;
if( pExpr ){ if( pExpr ){
CollSeq *pColl = pExpr->pColl; CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
/* Either pColl!=0 or there was an OOM failure. But if an OOM if( pColl ){
** failure we have quit before reaching this point. */
if( ALWAYS(pColl) ){
nExtra += (1 + sqlite3Strlen30(pColl->zName)); nExtra += (1 + sqlite3Strlen30(pColl->zName));
} }
} }
@@ -2756,6 +2755,7 @@ Index *sqlite3CreateIndex(
const char *zColName = pListItem->zName; const char *zColName = pListItem->zName;
Column *pTabCol; Column *pTabCol;
int requestedSortOrder; int requestedSortOrder;
CollSeq *pColl; /* Collating sequence */
char *zColl; /* Collation sequence name */ char *zColl; /* Collation sequence name */
for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){ for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
@@ -2768,14 +2768,11 @@ Index *sqlite3CreateIndex(
goto exit_create_index; goto exit_create_index;
} }
pIndex->aiColumn[i] = j; pIndex->aiColumn[i] = j;
/* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of if( pListItem->pExpr
** the way the "idxlist" non-terminal is constructed by the parser, && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
** if pListItem->pExpr is not null then either pListItem->pExpr->pColl ){
** must exist or else there must have been an OOM error. But if there
** was an OOM error, we would never reach this point. */
if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
int nColl; int nColl;
zColl = pListItem->pExpr->pColl->zName; zColl = pColl->zName;
nColl = sqlite3Strlen30(zColl) + 1; nColl = sqlite3Strlen30(zColl) + 1;
assert( nExtra>=nColl ); assert( nExtra>=nColl );
memcpy(zExtra, zColl, nColl); memcpy(zExtra, zColl, nColl);
@@ -3589,6 +3586,15 @@ int sqlite3OpenTempDatabase(Parse *pParse){
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse); Parse *pToplevel = sqlite3ParseToplevel(pParse);
#ifndef SQLITE_OMIT_TRIGGER
if( pToplevel!=pParse ){
/* This branch is taken if a trigger is currently being coded. In this
** case, set cookieGoto to a non-zero value to show that this function
** has been called. This is used by the sqlite3ExprCodeConstants()
** function. */
pParse->cookieGoto = -1;
}
#endif
if( pToplevel->cookieGoto==0 ){ if( pToplevel->cookieGoto==0 ){
Vdbe *v = sqlite3GetVdbe(pToplevel); Vdbe *v = sqlite3GetVdbe(pToplevel);
if( v==0 ) return; /* This only happens if there was a prior error */ if( v==0 ) return; /* This only happens if there was a prior error */

View File

@@ -31,7 +31,9 @@
** SELECT * FROM t1 WHERE (select a from t1); ** SELECT * FROM t1 WHERE (select a from t1);
*/ */
char sqlite3ExprAffinity(Expr *pExpr){ char sqlite3ExprAffinity(Expr *pExpr){
int op = pExpr->op; int op;
pExpr = sqlite3ExprSkipCollate(pExpr);
op = pExpr->op;
if( op==TK_SELECT ){ if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect ); assert( pExpr->flags&EP_xIsSelect );
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
@@ -56,66 +58,94 @@ char sqlite3ExprAffinity(Expr *pExpr){
} }
/* /*
** Set the explicit collating sequence for an expression to the ** Set the collating sequence for expression pExpr to be the collating
** collating sequence supplied in the second argument. ** sequence named by pToken. Return a pointer to a new Expr node that
** implements the COLLATE operator.
**
** If a memory allocation error occurs, that fact is recorded in pParse->db
** and the pExpr parameter is returned unchanged.
*/ */
Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){ Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
if( pExpr && pColl ){ if( pCollName->n>0 ){
pExpr->pColl = pColl; Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
pExpr->flags |= EP_ExpCollate; if( pNew ){
pNew->pLeft = pExpr;
pNew->flags |= EP_Collate;
pExpr = pNew;
}
}
return pExpr;
}
Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
Token s;
assert( zC!=0 );
s.z = zC;
s.n = sqlite3Strlen30(s.z);
return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
}
/*
** Skip over any TK_COLLATE and/or TK_AS operators at the root of
** an expression.
*/
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
pExpr = pExpr->pLeft;
} }
return pExpr; return pExpr;
} }
/* /*
** Set the collating sequence for expression pExpr to be the collating ** Return the collation sequence for the expression pExpr. If
** sequence named by pToken. Return a pointer to the revised expression. ** there is no defined collating sequence, return NULL.
** The collating sequence is marked as "explicit" using the EP_ExpCollate **
** flag. An explicit collating sequence will override implicit ** The collating sequence might be determined by a COLLATE operator
** collating sequences. ** or by the presence of a column with a defined collating sequence.
*/ ** COLLATE operators take first precedence. Left operands take
Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){ ** precedence over right operands.
char *zColl = 0; /* Dequoted name of collation sequence */
CollSeq *pColl;
sqlite3 *db = pParse->db;
zColl = sqlite3NameFromToken(db, pCollName);
pColl = sqlite3LocateCollSeq(pParse, zColl);
sqlite3ExprSetColl(pExpr, pColl);
sqlite3DbFree(db, zColl);
return pExpr;
}
/*
** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
*/ */
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
sqlite3 *db = pParse->db;
CollSeq *pColl = 0; CollSeq *pColl = 0;
Expr *p = pExpr; Expr *p = pExpr;
while( p ){ while( p ){
int op; int op = p->op;
pColl = p->pColl; if( op==TK_CAST || op==TK_UPLUS ){
if( pColl ) break; p = p->pLeft;
op = p->op; continue;
if( p->pTab!=0 && ( }
op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
)){ if( op==TK_COLLATE ){
/* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally if( db->init.busy ){
** a TK_COLUMN but was previously evaluated and cached in a register */ /* Do not report errors when parsing while the schema */
const char *zColl; pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0);
int j = p->iColumn; }else{
if( j>=0 ){ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
sqlite3 *db = pParse->db;
zColl = p->pTab->aCol[j].zColl;
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
pExpr->pColl = pColl;
} }
break; break;
} }
if( op!=TK_CAST && op!=TK_UPLUS ){ if( p->pTab!=0
&& (op==TK_AGG_COLUMN || op==TK_COLUMN
|| op==TK_REGISTER || op==TK_TRIGGER)
){
/* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */
int j = p->iColumn;
if( j>=0 ){
const char *zColl = p->pTab->aCol[j].zColl;
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
}
break;
}
if( p->flags & EP_Collate ){
if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
p = p->pLeft;
}else{
p = p->pRight;
}
}else{
break; break;
} }
p = p->pLeft;
} }
if( sqlite3CheckCollSeq(pParse, pColl) ){ if( sqlite3CheckCollSeq(pParse, pColl) ){
pColl = 0; pColl = 0;
@@ -219,12 +249,10 @@ CollSeq *sqlite3BinaryCompareCollSeq(
){ ){
CollSeq *pColl; CollSeq *pColl;
assert( pLeft ); assert( pLeft );
if( pLeft->flags & EP_ExpCollate ){ if( pLeft->flags & EP_Collate ){
assert( pLeft->pColl ); pColl = sqlite3ExprCollSeq(pParse, pLeft);
pColl = pLeft->pColl; }else if( pRight && (pRight->flags & EP_Collate)!=0 ){
}else if( pRight && pRight->flags & EP_ExpCollate ){ pColl = sqlite3ExprCollSeq(pParse, pRight);
assert( pRight->pColl );
pColl = pRight->pColl;
}else{ }else{
pColl = sqlite3ExprCollSeq(pParse, pLeft); pColl = sqlite3ExprCollSeq(pParse, pLeft);
if( !pColl ){ if( !pColl ){
@@ -454,17 +482,11 @@ void sqlite3ExprAttachSubtrees(
}else{ }else{
if( pRight ){ if( pRight ){
pRoot->pRight = pRight; pRoot->pRight = pRight;
if( pRight->flags & EP_ExpCollate ){ pRoot->flags |= EP_Collate & pRight->flags;
pRoot->flags |= EP_ExpCollate;
pRoot->pColl = pRight->pColl;
}
} }
if( pLeft ){ if( pLeft ){
pRoot->pLeft = pLeft; pRoot->pLeft = pLeft;
if( pLeft->flags & EP_ExpCollate ){ pRoot->flags |= EP_Collate & pLeft->flags;
pRoot->flags |= EP_ExpCollate;
pRoot->pColl = pLeft->pColl;
}
} }
exprSetHeight(pRoot); exprSetHeight(pRoot);
} }
@@ -722,7 +744,7 @@ static int dupedExprStructSize(Expr *p, int flags){
assert( !ExprHasProperty(p, EP_FromJoin) ); assert( !ExprHasProperty(p, EP_FromJoin) );
assert( (p->flags2 & EP2_MallocedToken)==0 ); assert( (p->flags2 & EP2_MallocedToken)==0 );
assert( (p->flags2 & EP2_Irreducible)==0 ); assert( (p->flags2 & EP2_Irreducible)==0 );
if( p->pLeft || p->pRight || p->pColl || p->x.pList ){ if( p->pLeft || p->pRight || p->x.pList ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced; nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{ }else{
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly; nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
@@ -2746,6 +2768,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
sqlite3ReleaseTempReg(pParse, r4); sqlite3ReleaseTempReg(pParse, r4);
break; break;
} }
case TK_COLLATE:
case TK_UPLUS: { case TK_UPLUS: {
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
break; break;
@@ -3115,6 +3138,12 @@ void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
case TK_ISNULL: zUniOp = "ISNULL"; break; case TK_ISNULL: zUniOp = "ISNULL"; break;
case TK_NOTNULL: zUniOp = "NOTNULL"; break; case TK_NOTNULL: zUniOp = "NOTNULL"; break;
case TK_COLLATE: {
sqlite3ExplainExpr(pOut, pExpr->pLeft);
sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
break;
}
case TK_AGG_FUNCTION: case TK_AGG_FUNCTION:
case TK_CONST_FUNC: case TK_CONST_FUNC:
case TK_FUNCTION: { case TK_FUNCTION: {
@@ -3333,6 +3362,9 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
case TK_REGISTER: { case TK_REGISTER: {
return WRC_Prune; return WRC_Prune;
} }
case TK_COLLATE: {
return WRC_Continue;
}
case TK_FUNCTION: case TK_FUNCTION:
case TK_AGG_FUNCTION: case TK_AGG_FUNCTION:
case TK_CONST_FUNC: { case TK_CONST_FUNC: {
@@ -3354,9 +3386,11 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
} }
if( isAppropriateForFactoring(pExpr) ){ if( isAppropriateForFactoring(pExpr) ){
int r1 = ++pParse->nMem; int r1 = ++pParse->nMem;
int r2; int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); /* If r2!=r1, it means that register r1 is never used. That is harmless
if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1); ** but suboptimal, so we want to know about the situation to fix it.
** Hence the following assert: */
assert( r2==r1 );
pExpr->op2 = pExpr->op; pExpr->op2 = pExpr->op;
pExpr->op = TK_REGISTER; pExpr->op = TK_REGISTER;
pExpr->iTable = r2; pExpr->iTable = r2;
@@ -3773,7 +3807,15 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
return 2; return 2;
} }
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( pA->op!=pB->op ) return 2; if( pA->op!=pB->op ){
if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
return 1;
}
if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
return 1;
}
return 2;
}
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2; if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2; if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
@@ -3785,11 +3827,9 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
}else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){ }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2; if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 2; return pA->op==TK_COLLATE ? 1 : 2;
} }
} }
if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
return 0; return 0;
} }

View File

@@ -511,12 +511,15 @@ static void fkScanChildren(
** expression to the parent key column defaults. */ ** expression to the parent key column defaults. */
if( pIdx ){ if( pIdx ){
Column *pCol; Column *pCol;
const char *zColl;
iCol = pIdx->aiColumn[i]; iCol = pIdx->aiColumn[i];
pCol = &pTab->aCol[iCol]; pCol = &pTab->aCol[iCol];
if( pTab->iPKey==iCol ) iCol = -1; if( pTab->iPKey==iCol ) iCol = -1;
pLeft->iTable = regData+iCol+1; pLeft->iTable = regData+iCol+1;
pLeft->affinity = pCol->affinity; pLeft->affinity = pCol->affinity;
pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl); zColl = pCol->zColl;
if( zColl==0 ) zColl = db->pDfltColl->zName;
pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
}else{ }else{
pLeft->iTable = regData; pLeft->iTable = regData;
pLeft->affinity = SQLITE_AFF_INTEGER; pLeft->affinity = SQLITE_AFF_INTEGER;

View File

@@ -192,6 +192,7 @@ static void instrFunc(
int N = 1; int N = 1;
int isText; int isText;
UNUSED_PARAMETER(argc);
typeHaystack = sqlite3_value_type(argv[0]); typeHaystack = sqlite3_value_type(argv[0]);
typeNeedle = sqlite3_value_type(argv[1]); typeNeedle = sqlite3_value_type(argv[1]);
if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return; if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;

View File

@@ -25,7 +25,7 @@ void sqlite3OpenTable(
int opcode /* OP_OpenRead or OP_OpenWrite */ int opcode /* OP_OpenRead or OP_OpenWrite */
){ ){
Vdbe *v; Vdbe *v;
if( IsVirtual(pTab) ) return; assert( !IsVirtual(pTab) );
v = sqlite3GetVdbe(p); v = sqlite3GetVdbe(p);
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName); sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
@@ -1274,25 +1274,20 @@ void sqlite3GenerateConstraintChecks(
onError = overrideError!=OE_Default ? overrideError : OE_Abort; onError = overrideError!=OE_Default ? overrideError : OE_Abort;
for(i=0; i<pCheck->nExpr; i++){ for(i=0; i<pCheck->nExpr; i++){
int allOk = sqlite3VdbeMakeLabel(v); int allOk = sqlite3VdbeMakeLabel(v);
Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0); sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
if( !db->mallocFailed ){ if( onError==OE_Ignore ){
assert( pDup!=0 ); sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL); }else{
if( onError==OE_Ignore ){ char *zConsName = pCheck->a[i].zName;
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
if( zConsName ){
zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
}else{ }else{
char *zConsName = pCheck->a[i].zName; zConsName = 0;
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
if( zConsName ){
zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
}else{
zConsName = 0;
}
sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
} }
sqlite3VdbeResolveLabel(v, allOk); sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
} }
sqlite3ExprDelete(db, pDup); sqlite3VdbeResolveLabel(v, allOk);
} }
} }
#endif /* !defined(SQLITE_OMIT_CHECK) */ #endif /* !defined(SQLITE_OMIT_CHECK) */

View File

@@ -228,6 +228,16 @@ int sqlite3JournalCreate(sqlite3_file *p){
return createFile((JournalFile *)p); return createFile((JournalFile *)p);
} }
/*
** The file-handle passed as the only argument is guaranteed to be an open
** file. It may or may not be of class JournalFile. If the file is a
** JournalFile, and the underlying file on disk has not yet been opened,
** return 0. Otherwise, return 1.
*/
int sqlite3JournalExists(sqlite3_file *p){
return (p->pMethods!=&JournalFileMethods || ((JournalFile *)p)->pReal!=0);
}
/* /*
** Return the number of bytes required to store a JournalFile that uses vfs ** Return the number of bytes required to store a JournalFile that uses vfs
** pVfs to create the underlying on-disk files. ** pVfs to create the underlying on-disk files.

View File

@@ -3581,6 +3581,9 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){
} }
} }
/* Forward declaration */
static int unixGetTempname(int nBuf, char *zBuf);
/* /*
** Information and control of an open file handle. ** Information and control of an open file handle.
*/ */
@@ -3618,6 +3621,14 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
return SQLITE_OK; return SQLITE_OK;
} }
case SQLITE_FCNTL_TEMPFILENAME: {
char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
if( zTFile ){
unixGetTempname(pFile->pVfs->mxPathname, zTFile);
*(char**)pArg = zTFile;
}
return SQLITE_OK;
}
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
/* The pager calls this method to signal that it has done /* The pager calls this method to signal that it has done
** a rollback and that the database is therefore unchanged and ** a rollback and that the database is therefore unchanged and

View File

@@ -2691,6 +2691,9 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
} }
} }
/* Forward declaration */
static int getTempname(int nBuf, char *zBuf);
/* /*
** Control and query of the open file handle. ** Control and query of the open file handle.
*/ */
@@ -2751,6 +2754,14 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
} }
return SQLITE_OK; return SQLITE_OK;
} }
case SQLITE_FCNTL_TEMPFILENAME: {
char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
if( zTFile ){
getTempname(pFile->pVfs->mxPathname, zTFile);
*(char**)pArg = zTFile;
}
return SQLITE_OK;
}
} }
return SQLITE_NOTFOUND; return SQLITE_NOTFOUND;
} }

View File

@@ -1941,12 +1941,13 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
** file should be closed and deleted. If this connection writes to ** file should be closed and deleted. If this connection writes to
** the database file, it will do so using an in-memory journal. ** the database file, it will do so using an in-memory journal.
*/ */
int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE
|| pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->journalMode==PAGER_JOURNALMODE_MEMORY
|| pPager->journalMode==PAGER_JOURNALMODE_WAL || pPager->journalMode==PAGER_JOURNALMODE_WAL
); );
sqlite3OsClose(pPager->jfd); sqlite3OsClose(pPager->jfd);
if( !pPager->tempFile ){ if( bDelete ){
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
} }
} }
@@ -3485,7 +3486,7 @@ void sqlite3PagerSetBusyhandler(
void **ap = (void **)&pPager->xBusyHandler; void **ap = (void **)&pPager->xBusyHandler;
assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
assert( ap[1]==pBusyHandlerArg ); assert( ap[1]==pBusyHandlerArg );
sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
} }
} }

View File

@@ -815,7 +815,7 @@ expr(A) ::= VARIABLE(X). {
spanSet(&A, &X, &X); spanSet(&A, &X, &X);
} }
expr(A) ::= expr(E) COLLATE ids(C). { expr(A) ::= expr(E) COLLATE ids(C). {
A.pExpr = sqlite3ExprSetCollByToken(pParse, E.pExpr, &C); A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C);
A.zStart = E.zStart; A.zStart = E.zStart;
A.zEnd = &C.z[C.n]; A.zEnd = &C.z[C.n];
} }
@@ -1140,22 +1140,14 @@ uniqueflag(A) ::= . {A = OE_None;}
idxlist_opt(A) ::= . {A = 0;} idxlist_opt(A) ::= . {A = 0;}
idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;} idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;}
idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). { idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). {
Expr *p = 0; Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
if( C.n>0 ){
p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
sqlite3ExprSetCollByToken(pParse, p, &C);
}
A = sqlite3ExprListAppend(pParse,X, p); A = sqlite3ExprListAppend(pParse,X, p);
sqlite3ExprListSetName(pParse,A,&Y,1); sqlite3ExprListSetName(pParse,A,&Y,1);
sqlite3ExprListCheckLength(pParse, A, "index"); sqlite3ExprListCheckLength(pParse, A, "index");
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z; if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
} }
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). { idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
Expr *p = 0; Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
if( C.n>0 ){
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
sqlite3ExprSetCollByToken(pParse, p, &C);
}
A = sqlite3ExprListAppend(pParse,0, p); A = sqlite3ExprListAppend(pParse,0, p);
sqlite3ExprListSetName(pParse, A, &Y, 1); sqlite3ExprListSetName(pParse, A, &Y, 1);
sqlite3ExprListCheckLength(pParse, A, "index"); sqlite3ExprListCheckLength(pParse, A, "index");

View File

@@ -68,6 +68,15 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
** from the result in the result-set. We might fix this someday. Or ** from the result in the result-set. We might fix this someday. Or
** then again, we might not... ** then again, we might not...
** **
** If the reference is followed by a COLLATE operator, then make sure
** the COLLATE operator is preserved. For example:
**
** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
**
** Should be transformed into:
**
** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
**
** The nSubquery parameter specifies how many levels of subquery the ** The nSubquery parameter specifies how many levels of subquery the
** alias is removed from the original expression. The usually value is ** alias is removed from the original expression. The usually value is
** zero but it might be more if the alias is contained within a subquery ** zero but it might be more if the alias is contained within a subquery
@@ -91,8 +100,9 @@ static void resolveAlias(
assert( pOrig!=0 ); assert( pOrig!=0 );
assert( pOrig->flags & EP_Resolved ); assert( pOrig->flags & EP_Resolved );
db = pParse->db; db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){ if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
pDup = sqlite3ExprDup(db, pOrig, 0);
incrAggFunctionDepth(pDup, nSubquery); incrAggFunctionDepth(pDup, nSubquery);
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0); pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
if( pDup==0 ) return; if( pDup==0 ) return;
@@ -100,32 +110,26 @@ static void resolveAlias(
pEList->a[iCol].iAlias = (u16)(++pParse->nAlias); pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
} }
pDup->iTable = pEList->a[iCol].iAlias; pDup->iTable = pEList->a[iCol].iAlias;
}else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
}else{
char *zToken = pOrig->u.zToken;
assert( zToken!=0 );
pOrig->u.zToken = 0;
pDup = sqlite3ExprDup(db, pOrig, 0);
pOrig->u.zToken = zToken;
if( pDup==0 ) return;
assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
pDup->flags2 |= EP2_MallocedToken;
pDup->u.zToken = sqlite3DbStrDup(db, zToken);
} }
if( pExpr->flags & EP_ExpCollate ){ if( pExpr->op==TK_COLLATE ){
pDup->pColl = pExpr->pColl; pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
pDup->flags |= EP_ExpCollate;
} }
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
** prevents ExprDelete() from deleting the Expr structure itself, ** prevents ExprDelete() from deleting the Expr structure itself,
** allowing it to be repopulated by the memcpy() on the following line. ** allowing it to be repopulated by the memcpy() on the following line.
** The pExpr->u.zToken might point into memory that will be freed by the
** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
** make a copy of the token before doing the sqlite3DbFree().
*/ */
ExprSetProperty(pExpr, EP_Static); ExprSetProperty(pExpr, EP_Static);
sqlite3ExprDelete(db, pExpr); sqlite3ExprDelete(db, pExpr);
memcpy(pExpr, pDup, sizeof(*pExpr)); memcpy(pExpr, pDup, sizeof(*pExpr));
if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
pExpr->flags2 |= EP2_MallocedToken;
}
sqlite3DbFree(db, pDup); sqlite3DbFree(db, pDup);
} }
@@ -812,7 +816,7 @@ static int resolveCompoundOrderBy(
int iCol = -1; int iCol = -1;
Expr *pE, *pDup; Expr *pE, *pDup;
if( pItem->done ) continue; if( pItem->done ) continue;
pE = pItem->pExpr; pE = sqlite3ExprSkipCollate(pItem->pExpr);
if( sqlite3ExprIsInteger(pE, &iCol) ){ if( sqlite3ExprIsInteger(pE, &iCol) ){
if( iCol<=0 || iCol>pEList->nExpr ){ if( iCol<=0 || iCol>pEList->nExpr ){
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
@@ -830,14 +834,20 @@ static int resolveCompoundOrderBy(
} }
} }
if( iCol>0 ){ if( iCol>0 ){
CollSeq *pColl = pE->pColl; /* Convert the ORDER BY term into an integer column number iCol,
int flags = pE->flags & EP_ExpCollate; ** taking care to preserve the COLLATE clause if it exists */
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
if( pNew==0 ) return 1;
pNew->flags |= EP_IntValue;
pNew->u.iValue = iCol;
if( pItem->pExpr==pE ){
pItem->pExpr = pNew;
}else{
assert( pItem->pExpr->op==TK_COLLATE );
assert( pItem->pExpr->pLeft==pE );
pItem->pExpr->pLeft = pNew;
}
sqlite3ExprDelete(db, pE); sqlite3ExprDelete(db, pE);
pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
if( pE==0 ) return 1;
pE->pColl = pColl;
pE->flags |= EP_IntValue | flags;
pE->u.iValue = iCol;
pItem->iOrderByCol = (u16)iCol; pItem->iOrderByCol = (u16)iCol;
pItem->done = 1; pItem->done = 1;
}else{ }else{
@@ -942,11 +952,11 @@ static int resolveOrderGroupBy(
pItem->iOrderByCol = (u16)iCol; pItem->iOrderByCol = (u16)iCol;
continue; continue;
} }
if( sqlite3ExprIsInteger(pE, &iCol) ){ if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
/* The ORDER BY term is an integer constant. Again, set the column /* The ORDER BY term is an integer constant. Again, set the column
** number so that sqlite3ResolveOrderGroupBy() will convert the ** number so that sqlite3ResolveOrderGroupBy() will convert the
** order-by term to a copy of the result-set expression */ ** order-by term to a copy of the result-set expression */
if( iCol<1 ){ if( iCol<1 || iCol>0xffff ){
resolveOutOfRangeError(pParse, zType, i+1, nResult); resolveOutOfRangeError(pParse, zType, i+1, nResult);
return 1; return 1;
} }

View File

@@ -1335,7 +1335,7 @@ static int selectColumnsFromExprList(
for(i=0, pCol=aCol; i<nCol; i++, pCol++){ for(i=0, pCol=aCol; i<nCol; i++, pCol++){
/* Get an appropriate name for the column /* Get an appropriate name for the column
*/ */
p = pEList->a[i].pExpr; p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue) assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
|| p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 ); || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
if( (zName = pEList->a[i].zName)!=0 ){ if( (zName = pEList->a[i].zName)!=0 ){
@@ -2333,12 +2333,13 @@ static int multiSelectOrderBy(
for(i=0; i<nOrderBy; i++){ for(i=0; i<nOrderBy; i++){
CollSeq *pColl; CollSeq *pColl;
Expr *pTerm = pOrderBy->a[i].pExpr; Expr *pTerm = pOrderBy->a[i].pExpr;
if( pTerm->flags & EP_ExpCollate ){ if( pTerm->flags & EP_Collate ){
pColl = pTerm->pColl; pColl = sqlite3ExprCollSeq(pParse, pTerm);
}else{ }else{
pColl = multiSelectCollSeq(pParse, p, aPermute[i]); pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
pTerm->flags |= EP_ExpCollate; if( pColl==0 ) pColl = db->pDfltColl;
pTerm->pColl = pColl; pOrderBy->a[i].pExpr =
sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
} }
pKeyMerge->aColl[i] = pColl; pKeyMerge->aColl[i] = pColl;
pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder; pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
@@ -2541,6 +2542,7 @@ static int multiSelectOrderBy(
sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
(char*)pKeyMerge, P4_KEYINFO_HANDOFF); (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
/* Release temporary registers /* Release temporary registers
@@ -2608,9 +2610,6 @@ static Expr *substExpr(
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr ); assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
assert( pExpr->pLeft==0 && pExpr->pRight==0 ); assert( pExpr->pLeft==0 && pExpr->pRight==0 );
pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0); pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
if( pNew && pExpr->pColl ){
pNew->pColl = pExpr->pColl;
}
sqlite3ExprDelete(db, pExpr); sqlite3ExprDelete(db, pExpr);
pExpr = pNew; pExpr = pNew;
} }
@@ -3950,6 +3949,15 @@ int sqlite3Select(
int addrEof; int addrEof;
pItem->regReturn = ++pParse->nMem; pItem->regReturn = ++pParse->nMem;
addrEof = ++pParse->nMem; addrEof = ++pParse->nMem;
/* Before coding the OP_Goto to jump to the start of the main routine,
** ensure that the jump to the verify-schema routine has already
** been coded. Otherwise, the verify-schema would likely be coded as
** part of the co-routine. If the main routine then accessed the
** database before invoking the co-routine for the first time (for
** example to initialize a LIMIT register from a sub-select), it would
** be doing so without having verified the schema version and obtained
** the required db locks. See ticket d6b36be38. */
sqlite3CodeVerifySchema(pParse, -1);
sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeAddOp0(v, OP_Goto);
addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor); addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor);
sqlite3VdbeChangeP5(v, 1); sqlite3VdbeChangeP5(v, 1);

View File

@@ -541,6 +541,9 @@ static void output_c_string(FILE *out, const char *z){
if( c=='\\' ){ if( c=='\\' ){
fputc(c, out); fputc(c, out);
fputc(c, out); fputc(c, out);
}else if( c=='"' ){
fputc('\\', out);
fputc('"', out);
}else if( c=='\t' ){ }else if( c=='\t' ){
fputc('\\', out); fputc('\\', out);
fputc('t', out); fputc('t', out);
@@ -796,14 +799,14 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
if( p->cnt++==0 && p->showHeader ){ if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){ for(i=0; i<nArg; i++){
output_c_string(p->out,azCol[i] ? azCol[i] : ""); output_c_string(p->out,azCol[i] ? azCol[i] : "");
fprintf(p->out, "%s", p->separator); if(i<nArg-1) fprintf(p->out, "%s", p->separator);
} }
fprintf(p->out,"\n"); fprintf(p->out,"\n");
} }
if( azArg==0 ) break; if( azArg==0 ) break;
for(i=0; i<nArg; i++){ for(i=0; i<nArg; i++){
output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
fprintf(p->out, "%s", p->separator); if(i<nArg-1) fprintf(p->out, "%s", p->separator);
} }
fprintf(p->out,"\n"); fprintf(p->out,"\n");
break; break;
@@ -2018,6 +2021,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
p->mode = MODE_Html; p->mode = MODE_Html;
}else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){ }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
p->mode = MODE_Tcl; p->mode = MODE_Tcl;
sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
}else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){ }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
p->mode = MODE_Csv; p->mode = MODE_Csv;
sqlite3_snprintf(sizeof(p->separator), p->separator, ","); sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
@@ -2711,7 +2715,7 @@ static int process_input(struct callback_data *p, FILE *in){
free(zSql); free(zSql);
} }
free(zLine); free(zLine);
return errCnt; return errCnt>0;
} }
/* /*

View File

@@ -852,7 +852,6 @@ struct sqlite3_io_methods {
** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] ** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA]
** file control occurs at the beginning of pragma statement analysis and so ** file control occurs at the beginning of pragma statement analysis and so
** it is able to override built-in [PRAGMA] statements. ** it is able to override built-in [PRAGMA] statements.
** </ul>
** **
** <li>[[SQLITE_FCNTL_BUSYHANDLER]] ** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
** ^This file-control may be invoked by SQLite on the database file handle ** ^This file-control may be invoked by SQLite on the database file handle
@@ -864,6 +863,16 @@ struct sqlite3_io_methods {
** the array as the only argument. If it returns non-zero, then the operation ** the array as the only argument. If it returns non-zero, then the operation
** should be retried. If it returns zero, the custom VFS should abandon the ** should be retried. If it returns zero, the custom VFS should abandon the
** current operation. ** current operation.
**
** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
** ^Application can invoke this file-control to have SQLite generate a
** temporary filename using the same algorithm that is followed to generate
** temporary filenames for TEMP tables and other internal uses. The
** argument should be a char** which will be filled with the filename
** written into memory obtained from [sqlite3_malloc()]. The caller should
** invoke [sqlite3_free()] on the result to avoid a memory leak.
**
** </ul>
*/ */
#define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_LOCKSTATE 1
#define SQLITE_GET_LOCKPROXYFILE 2 #define SQLITE_GET_LOCKPROXYFILE 2
@@ -880,6 +889,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 #define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13
#define SQLITE_FCNTL_PRAGMA 14 #define SQLITE_FCNTL_PRAGMA 14
#define SQLITE_FCNTL_BUSYHANDLER 15 #define SQLITE_FCNTL_BUSYHANDLER 15
#define SQLITE_FCNTL_TEMPFILENAME 16
/* /*
** CAPI3REF: Mutex Handle ** CAPI3REF: Mutex Handle

View File

@@ -1158,19 +1158,7 @@ struct Column {
** structure. Conceptually, a collating sequence consists of a name and ** structure. Conceptually, a collating sequence consists of a name and
** a comparison routine that defines the order of that sequence. ** a comparison routine that defines the order of that sequence.
** **
** There may two separate implementations of the collation function, one ** If CollSeq.xCmp is NULL, it means that the
** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
** native byte order. When a collation sequence is invoked, SQLite selects
** the version that will require the least expensive encoding
** translations, if any.
**
** The CollSeq.pUser member variable is an extra parameter that passed in
** as the first argument to the UTF-8 comparison function, xCmp.
** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
** xCmp16.
**
** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
** collating sequence is undefined. Indices built on an undefined ** collating sequence is undefined. Indices built on an undefined
** collating sequence may not be read or written. ** collating sequence may not be read or written.
*/ */
@@ -1698,7 +1686,6 @@ struct Expr {
ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */ ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */ Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
} x; } x;
CollSeq *pColl; /* The collation type of the column or 0 */
/* If the EP_Reduced flag is set in the Expr.flags mask, then no /* If the EP_Reduced flag is set in the Expr.flags mask, then no
** space is allocated for the fields below this point. An attempt to ** space is allocated for the fields below this point. An attempt to
@@ -1734,7 +1721,7 @@ struct Expr {
#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */ #define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */ #define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */ #define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */ #define EP_Collate 0x0100 /* Tree contains a TK_COLLATE opeartor */
#define EP_FixedDest 0x0200 /* Result needed in a specific register */ #define EP_FixedDest 0x0200 /* Result needed in a specific register */
#define EP_IntValue 0x0400 /* Integer value contained in u.iValue */ #define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */ #define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
@@ -2355,6 +2342,7 @@ struct AuthContext {
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */ #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
/* /*
* Each trigger present in the database schema is stored as an instance of * Each trigger present in the database schema is stored as an instance of
@@ -3046,8 +3034,9 @@ int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
Expr *sqlite3ExprSetColl(Expr*, CollSeq*); Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*); Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
Expr *sqlite3ExprSkipCollate(Expr*);
int sqlite3CheckCollSeq(Parse *, CollSeq *); int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckObjectName(Parse *, const char *); int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int); void sqlite3VdbeSetChanges(sqlite3 *, int);
@@ -3265,8 +3254,10 @@ int sqlite3FindInIndex(Parse *, Expr *, int*);
int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
int sqlite3JournalSize(sqlite3_vfs *); int sqlite3JournalSize(sqlite3_vfs *);
int sqlite3JournalCreate(sqlite3_file *); int sqlite3JournalCreate(sqlite3_file *);
int sqlite3JournalExists(sqlite3_file *p);
#else #else
#define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile) #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
#define sqlite3JournalExists(p) 1
#endif #endif
void sqlite3MemJournalOpen(sqlite3_file *); void sqlite3MemJournalOpen(sqlite3_file *);

View File

@@ -5321,6 +5321,38 @@ static int file_control_vfsname(
return TCL_OK; return TCL_OK;
} }
/*
** tclcmd: file_control_tempfilename DB ?AUXDB?
**
** Return a string that is a temporary filename
*/
static int file_control_tempfilename(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3 *db;
const char *zDbName = "main";
char *zTName = 0;
if( objc!=2 && objc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
return TCL_ERROR;
}
if( objc==3 ){
zDbName = Tcl_GetString(objv[2]);
}
sqlite3_file_control(db, zDbName, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTName);
Tcl_AppendResult(interp, zTName, (char*)0);
sqlite3_free(zTName);
return TCL_OK;
}
/* /*
** tclcmd: sqlite3_vfs_list ** tclcmd: sqlite3_vfs_list
@@ -6150,6 +6182,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "file_control_persist_wal", file_control_persist_wal, 0 }, { "file_control_persist_wal", file_control_persist_wal, 0 },
{ "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0}, { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
{ "file_control_vfsname", file_control_vfsname, 0 }, { "file_control_vfsname", file_control_vfsname, 0 },
{ "file_control_tempfilename", file_control_tempfilename, 0 },
{ "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_vfs_list", vfs_list, 0 },
{ "sqlite3_create_function_v2", test_create_function_v2, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 },

View File

@@ -720,8 +720,8 @@ static int test_memdebug_settitle(
#ifdef SQLITE_MEMDEBUG #ifdef SQLITE_MEMDEBUG
{ {
const char *zTitle; const char *zTitle;
zTitle = Tcl_GetString(objv[1]);
extern int sqlite3MemdebugSettitle(const char*); extern int sqlite3MemdebugSettitle(const char*);
zTitle = Tcl_GetString(objv[1]);
sqlite3MemdebugSettitle(zTitle); sqlite3MemdebugSettitle(zTitle);
} }
#endif #endif

View File

@@ -390,7 +390,7 @@ static void testSqllogStmt(struct SLConn *p, const char *zSql){
** The SQLITE_CONFIG_SQLLOG callback registered by sqlite3_init_sqllog(). ** The SQLITE_CONFIG_SQLLOG callback registered by sqlite3_init_sqllog().
*/ */
static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int eType){ static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int eType){
struct SLConn *p; struct SLConn *p = 0;
sqlite3_mutex *master = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex *master = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
assert( eType==0 || eType==1 || eType==2 ); assert( eType==0 || eType==1 || eType==2 );

View File

@@ -475,6 +475,7 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
case SQLITE_FCNTL_PERSIST_WAL: zOp = "PERSIST_WAL"; break; case SQLITE_FCNTL_PERSIST_WAL: zOp = "PERSIST_WAL"; break;
case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break; case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break; case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME"; break;
case 0xca093fa0: zOp = "DB_UNCHANGED"; break; case 0xca093fa0: zOp = "DB_UNCHANGED"; break;
case SQLITE_FCNTL_PRAGMA: { case SQLITE_FCNTL_PRAGMA: {
const char *const* a = (const char*const*)pArg; const char *const* a = (const char*const*)pArg;
@@ -496,7 +497,8 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
*(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z", *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z",
pInfo->zVfsName, *(char**)pArg); pInfo->zVfsName, *(char**)pArg);
} }
if( op==SQLITE_FCNTL_PRAGMA && rc==SQLITE_OK && *(char**)pArg ){ if( (op==SQLITE_FCNTL_PRAGMA || op==SQLITE_FCNTL_TEMPFILENAME)
&& rc==SQLITE_OK && *(char**)pArg ){
vfstrace_printf(pInfo, "%s.xFileControl(%s,%s) returns %s", vfstrace_printf(pInfo, "%s.xFileControl(%s,%s) returns %s",
pInfo->zVfsName, p->zFName, zOp, *(char**)pArg); pInfo->zVfsName, p->zFName, zOp, *(char**)pArg);
} }

View File

@@ -729,6 +729,15 @@ static int codeTriggerProgram(
*/ */
pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
/* Clear the cookieGoto flag. When coding triggers, the cookieGoto
** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
** that it is not safe to refactor constants (this happens after the
** start of the first loop in the SQL statement is coded - at that
** point code may be conditionally executed, so it is no longer safe to
** initialize constant register values). */
assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
pParse->cookieGoto = 0;
switch( pStep->op ){ switch( pStep->op ){
case TK_UPDATE: { case TK_UPDATE: {
sqlite3Update(pParse, sqlite3Update(pParse,

View File

@@ -432,7 +432,9 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
** Print the value of a register for tracing purposes: ** Print the value of a register for tracing purposes:
*/ */
static void memTracePrint(FILE *out, Mem *p){ static void memTracePrint(FILE *out, Mem *p){
if( p->flags & MEM_Null ){ if( p->flags & MEM_Invalid ){
fprintf(out, " undefined");
}else if( p->flags & MEM_Null ){
fprintf(out, " NULL"); fprintf(out, " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
fprintf(out, " si:%lld", p->u.i); fprintf(out, " si:%lld", p->u.i);
@@ -1087,6 +1089,9 @@ case OP_Copy: {
while( 1 ){ while( 1 ){
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
Deephemeralize(pOut); Deephemeralize(pOut);
#ifdef SQLITE_DEBUG
pOut->pScopyFrom = 0;
#endif
REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut); REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
if( (n--)==0 ) break; if( (n--)==0 ) break;
pOut++; pOut++;
@@ -1897,9 +1902,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** Set the permutation used by the OP_Compare operator to be the array ** Set the permutation used by the OP_Compare operator to be the array
** of integers in P4. ** of integers in P4.
** **
** The permutation is only valid until the next OP_Permutation, OP_Compare, ** The permutation is only valid until the next OP_Compare that has
** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur ** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
** immediately prior to the OP_Compare. ** occur immediately prior to the OP_Compare.
*/ */
case OP_Permutation: { case OP_Permutation: {
assert( pOp->p4type==P4_INTARRAY ); assert( pOp->p4type==P4_INTARRAY );
@@ -1908,12 +1913,17 @@ case OP_Permutation: {
break; break;
} }
/* Opcode: Compare P1 P2 P3 P4 * /* Opcode: Compare P1 P2 P3 P4 P5
** **
** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
** the comparison for use by the next OP_Jump instruct. ** the comparison for use by the next OP_Jump instruct.
** **
** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is
** determined by the most recent OP_Permutation operator. If the
** OPFLAG_PERMUTE bit is clear, then register are compared in sequential
** order.
**
** P4 is a KeyInfo structure that defines collating sequences and sort ** P4 is a KeyInfo structure that defines collating sequences and sort
** orders for the comparison. The permutation applies to registers ** orders for the comparison. The permutation applies to registers
** only. The KeyInfo elements are used sequentially. ** only. The KeyInfo elements are used sequentially.
@@ -1932,6 +1942,7 @@ case OP_Compare: {
CollSeq *pColl; /* Collating sequence to use on this term */ CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */ int bRev; /* True for DESCENDING sort order */
if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
n = pOp->p3; n = pOp->p3;
pKeyInfo = pOp->p4.pKeyInfo; pKeyInfo = pOp->p4.pKeyInfo;
assert( n>0 ); assert( n>0 );
@@ -3310,7 +3321,7 @@ case OP_OpenEphemeral: {
break; break;
} }
/* Opcode: OpenSorter P1 P2 * P4 * /* Opcode: SorterOpen P1 P2 * P4 *
** **
** This opcode works like OP_OpenEphemeral except that it opens ** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large ** a transient index that is specifically designed to sort large

View File

@@ -724,6 +724,7 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
addr = p->nOp - 1; addr = p->nOp - 1;
} }
pOp = &p->aOp[addr]; pOp = &p->aOp[addr];
assert( pOp->p4type==P4_NOTUSED || pOp->p4type==P4_INT32 );
freeP4(db, pOp->p4type, pOp->p4.p); freeP4(db, pOp->p4type, pOp->p4.p);
pOp->p4.p = 0; pOp->p4.p = 0;
if( n==P4_INT32 ){ if( n==P4_INT32 ){
@@ -866,22 +867,18 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
i = sqlite3Strlen30(zTemp); i = sqlite3Strlen30(zTemp);
for(j=0; j<pKeyInfo->nField; j++){ for(j=0; j<pKeyInfo->nField; j++){
CollSeq *pColl = pKeyInfo->aColl[j]; CollSeq *pColl = pKeyInfo->aColl[j];
if( pColl ){ const char *zColl = pColl ? pColl->zName : "nil";
int n = sqlite3Strlen30(pColl->zName); int n = sqlite3Strlen30(zColl);
if( i+n>nTemp-6 ){ if( i+n>nTemp-6 ){
memcpy(&zTemp[i],",...",4); memcpy(&zTemp[i],",...",4);
break; break;
}
zTemp[i++] = ',';
if( pKeyInfo->aSortOrder[j] ){
zTemp[i++] = '-';
}
memcpy(&zTemp[i], pColl->zName,n+1);
i += n;
}else if( i+4<nTemp-6 ){
memcpy(&zTemp[i],",nil",4);
i += 4;
} }
zTemp[i++] = ',';
if( pKeyInfo->aSortOrder[j] ){
zTemp[i++] = '-';
}
memcpy(&zTemp[i], zColl, n+1);
i += n;
} }
zTemp[i++] = ')'; zTemp[i++] = ')';
zTemp[i] = 0; zTemp[i] = 0;
@@ -2482,7 +2479,7 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
sqlite3DbFree(db, p->zSql); sqlite3DbFree(db, p->zSql);
sqlite3DbFree(db, p->pFree); sqlite3DbFree(db, p->pFree);
#if defined(SQLITE_ENABLE_TREE_EXPLAIN) #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
sqlite3DbFree(db, p->zExplain); sqlite3_free(p->zExplain);
sqlite3DbFree(db, p->pExplain); sqlite3DbFree(db, p->pExplain);
#endif #endif
} }

View File

@@ -563,23 +563,32 @@ static int allowedOp(int op){
** Commute a comparison operator. Expressions of the form "X op Y" ** Commute a comparison operator. Expressions of the form "X op Y"
** are converted into "Y op X". ** are converted into "Y op X".
** **
** If a collation sequence is associated with either the left or right ** If left/right precendence rules come into play when determining the
** collating
** side of the comparison, it remains associated with the same side after ** side of the comparison, it remains associated with the same side after
** the commutation. So "Y collate NOCASE op X" becomes ** the commutation. So "Y collate NOCASE op X" becomes
** "X collate NOCASE op Y". This is because any collation sequence on ** "X op Y". This is because any collation sequence on
** the left hand side of a comparison overrides any collation sequence ** the left hand side of a comparison overrides any collation sequence
** attached to the right. For the same reason the EP_ExpCollate flag ** attached to the right. For the same reason the EP_Collate flag
** is not commuted. ** is not commuted.
*/ */
static void exprCommute(Parse *pParse, Expr *pExpr){ static void exprCommute(Parse *pParse, Expr *pExpr){
u16 expRight = (pExpr->pRight->flags & EP_ExpCollate); u16 expRight = (pExpr->pRight->flags & EP_Collate);
u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate); u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN ); assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight); if( expRight==expLeft ){
pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); /* Either X and Y both have COLLATE operator or neither do */
SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl); if( expRight ){
pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft; /* Both X and Y have COLLATE operators. Make sure X is always
pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight; ** used by clearing the EP_Collate flag from Y. */
pExpr->pRight->flags &= ~EP_Collate;
}else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
/* Neither X nor Y have COLLATE operators, but X has a non-default
** collating sequence. So add the EP_Collate marker on X to cause
** it to be searched first. */
pExpr->pLeft->flags |= EP_Collate;
}
}
SWAP(Expr*,pExpr->pRight,pExpr->pLeft); SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
if( pExpr->op>=TK_GT ){ if( pExpr->op>=TK_GT ){
assert( TK_LT==TK_GT+2 ); assert( TK_LT==TK_GT+2 );
@@ -656,12 +665,12 @@ static WhereTerm *findTerm(
*/ */
assert(pX->pLeft); assert(pX->pLeft);
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
assert(pColl || pParse->nErr); if( pColl==0 ) pColl = pParse->db->pDfltColl;
for(j=0; pIdx->aiColumn[j]!=iColumn; j++){ for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
if( NEVER(j>=pIdx->nColumn) ) return 0; if( NEVER(j>=pIdx->nColumn) ) return 0;
} }
if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue; if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
} }
return pTerm; return pTerm;
} }
@@ -1179,7 +1188,7 @@ static void exprAnalyze(
} }
pTerm = &pWC->a[idxTerm]; pTerm = &pWC->a[idxTerm];
pMaskSet = pWC->pMaskSet; pMaskSet = pWC->pMaskSet;
pExpr = pTerm->pExpr; pExpr = sqlite3ExprSkipCollate(pTerm->pExpr);
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft); prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
op = pExpr->op; op = pExpr->op;
if( op==TK_IN ){ if( op==TK_IN ){
@@ -1206,8 +1215,8 @@ static void exprAnalyze(
pTerm->iParent = -1; pTerm->iParent = -1;
pTerm->eOperator = 0; pTerm->eOperator = 0;
if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){ if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
Expr *pLeft = pExpr->pLeft; Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
Expr *pRight = pExpr->pRight; Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
if( pLeft->op==TK_COLUMN ){ if( pLeft->op==TK_COLUMN ){
pTerm->leftCursor = pLeft->iTable; pTerm->leftCursor = pLeft->iTable;
pTerm->u.leftColumn = pLeft->iColumn; pTerm->u.leftColumn = pLeft->iColumn;
@@ -1235,7 +1244,7 @@ static void exprAnalyze(
pNew = pTerm; pNew = pTerm;
} }
exprCommute(pParse, pDup); exprCommute(pParse, pDup);
pLeft = pDup->pLeft; pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
pNew->leftCursor = pLeft->iTable; pNew->leftCursor = pLeft->iTable;
pNew->u.leftColumn = pLeft->iColumn; pNew->u.leftColumn = pLeft->iColumn;
testcase( (prereqLeft | extraRight) != prereqLeft ); testcase( (prereqLeft | extraRight) != prereqLeft );
@@ -1314,7 +1323,7 @@ static void exprAnalyze(
Expr *pNewExpr2; Expr *pNewExpr2;
int idxNew1; int idxNew1;
int idxNew2; int idxNew2;
CollSeq *pColl; /* Collating sequence to use */ Token sCollSeqName; /* Name of collating sequence */
pLeft = pExpr->x.pList->a[1].pExpr; pLeft = pExpr->x.pList->a[1].pExpr;
pStr2 = sqlite3ExprDup(db, pStr1, 0); pStr2 = sqlite3ExprDup(db, pStr1, 0);
@@ -1336,16 +1345,19 @@ static void exprAnalyze(
} }
*pC = c + 1; *pC = c + 1;
} }
pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0); sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
sCollSeqName.n = 6;
pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
pNewExpr1 = sqlite3PExpr(pParse, TK_GE, pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl), sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
pStr1, 0); pStr1, 0);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew1==0 ); testcase( idxNew1==0 );
exprAnalyze(pSrc, pWC, idxNew1); exprAnalyze(pSrc, pWC, idxNew1);
pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
pNewExpr2 = sqlite3PExpr(pParse, TK_LT, pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl), sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
pStr2, 0); pStr2, 0);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew2==0 ); testcase( idxNew2==0 );
exprAnalyze(pSrc, pWC, idxNew2); exprAnalyze(pSrc, pWC, idxNew2);
@@ -1463,12 +1475,12 @@ static int findIndexCol(
const char *zColl = pIdx->azColl[iCol]; const char *zColl = pIdx->azColl[iCol];
for(i=0; i<pList->nExpr; i++){ for(i=0; i<pList->nExpr; i++){
Expr *p = pList->a[i].pExpr; Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
if( p->op==TK_COLUMN if( p->op==TK_COLUMN
&& p->iColumn==pIdx->aiColumn[iCol] && p->iColumn==pIdx->aiColumn[iCol]
&& p->iTable==iBase && p->iTable==iBase
){ ){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, p); CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){ if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
return i; return i;
} }
@@ -1515,7 +1527,7 @@ static int isDistinctIndex(
*/ */
for(i=0; i<pDistinct->nExpr; i++){ for(i=0; i<pDistinct->nExpr; i++){
WhereTerm *pTerm; WhereTerm *pTerm;
Expr *p = pDistinct->a[i].pExpr; Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
if( p->op!=TK_COLUMN ) return 0; if( p->op!=TK_COLUMN ) return 0;
pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0); pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
if( pTerm ){ if( pTerm ){
@@ -1567,7 +1579,7 @@ static int isDistinctRedundant(
** current SELECT is a correlated sub-query. ** current SELECT is a correlated sub-query.
*/ */
for(i=0; i<pDistinct->nExpr; i++){ for(i=0; i<pDistinct->nExpr; i++){
Expr *p = pDistinct->a[i].pExpr; Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1; if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
} }
@@ -2853,7 +2865,7 @@ static int isSortingIndex(
/* If the next term of the ORDER BY clause refers to anything other than /* If the next term of the ORDER BY clause refers to anything other than
** a column in the "base" table, then this index will not be of any ** a column in the "base" table, then this index will not be of any
** further use in handling the ORDER BY. */ ** further use in handling the ORDER BY. */
pOBExpr = pOBItem->pExpr; pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr);
if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){ if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
break; break;
} }
@@ -2879,7 +2891,7 @@ static int isSortingIndex(
** clause entry. Set isMatch to 1 if they both match. */ ** clause entry. Set isMatch to 1 if they both match. */
if( pOBExpr->iColumn==iColumn ){ if( pOBExpr->iColumn==iColumn ){
if( zColl ){ if( zColl ){
pColl = sqlite3ExprCollSeq(pParse, pOBExpr); pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr);
if( !pColl ) pColl = db->pDfltColl; if( !pColl ) pColl = db->pDfltColl;
isMatch = sqlite3StrICmp(pColl->zName, zColl)==0; isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
}else{ }else{
@@ -3020,6 +3032,11 @@ static void bestBtreeIndex(WhereBestIdx *p){
tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */ tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
int aiColumnPk = -1; /* The aColumn[] value for the sPk index */ int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */ int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */
int nPriorSat; /* ORDER BY terms satisfied by outer loops */
int nOrderBy; /* Number of ORDER BY terms */
char bSortInit; /* Initializer for bSort in inner loop */
char bDistInit; /* Initializer for bDist in inner loop */
/* Initialize the cost to a worst-case value */ /* Initialize the cost to a worst-case value */
memset(&p->cost, 0, sizeof(p->cost)); memset(&p->cost, 0, sizeof(p->cost));
@@ -3069,6 +3086,17 @@ static void bestBtreeIndex(WhereBestIdx *p){
pIdx = 0; pIdx = 0;
} }
nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
if( p->i ){
nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
bSortInit = nPriorSat<nOrderBy;
bDistInit = 0;
}else{
nPriorSat = 0;
bSortInit = nOrderBy>0;
bDistInit = p->pDistinct!=0;
}
/* Loop over all indices looking for the best one to use /* Loop over all indices looking for the best one to use
*/ */
for(; pProbe; pIdx=pProbe=pProbe->pNext){ for(; pProbe; pIdx=pProbe=pProbe->pNext){
@@ -3146,11 +3174,9 @@ static void bestBtreeIndex(WhereBestIdx *p){
int nInMul = 1; /* Number of distinct equalities to lookup */ int nInMul = 1; /* Number of distinct equalities to lookup */
double rangeDiv = (double)1; /* Estimated reduction in search space */ double rangeDiv = (double)1; /* Estimated reduction in search space */
int nBound = 0; /* Number of range constraints seen */ int nBound = 0; /* Number of range constraints seen */
int bSort; /* True if external sort required */ char bSort = bSortInit; /* True if external sort required */
int bDist; /* True if index cannot help with DISTINCT */ char bDist = bDistInit; /* True if index cannot help with DISTINCT */
int bLookup = 0; /* True if not a covering index */ char bLookup = 0; /* True if not a covering index */
int nPriorSat; /* ORDER BY terms satisfied by outer loops */
int nOrderBy; /* Number of ORDER BY terms */
WhereTerm *pTerm; /* A single term of the WHERE clause */ WhereTerm *pTerm; /* A single term of the WHERE clause */
#ifdef SQLITE_ENABLE_STAT3 #ifdef SQLITE_ENABLE_STAT3
WhereTerm *pFirstTerm = 0; /* First term matching the index */ WhereTerm *pFirstTerm = 0; /* First term matching the index */
@@ -3161,16 +3187,7 @@ static void bestBtreeIndex(WhereBestIdx *p){
pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk") pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
)); ));
memset(&pc, 0, sizeof(pc)); memset(&pc, 0, sizeof(pc));
nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0; pc.plan.nOBSat = nPriorSat;
if( p->i ){
nPriorSat = pc.plan.nOBSat = p->aLevel[p->i-1].plan.nOBSat;
bSort = nPriorSat<nOrderBy;
bDist = 0;
}else{
nPriorSat = pc.plan.nOBSat = 0;
bSort = nOrderBy>0;
bDist = p->pDistinct!=0;
}
/* Determine the values of pc.plan.nEq and nInMul */ /* Determine the values of pc.plan.nEq and nInMul */
for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){ for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
@@ -5257,6 +5274,8 @@ WhereInfo *sqlite3WhereBegin(
const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
int iCur = pTabItem->iCursor; int iCur = pTabItem->iCursor;
sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB); sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
}else if( IsVirtual(pTab) ){
/* noop */
}else }else
#endif #endif
if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0

View File

@@ -63,8 +63,7 @@ do_execsql_test 2.1 {
CREATE TABLE t1(a, b); CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b); CREATE INDEX i1 ON t1(a, b);
} }
do_test 2.2 { file size test.db } [expr $AUTOVACUUM ? 4096 : 3072]
do_test 2.2 { file size test.db } 3072
do_test 2.3 { do_test 2.3 {
sqlite3 db1 test.db2 sqlite3 db1 test.db2
@@ -90,8 +89,7 @@ do_execsql_test 3.1 {
CREATE TABLE t1(a, b); CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b); CREATE INDEX i1 ON t1(a, b);
} }
do_test 3.2 { file size test.db } [expr $AUTOVACUUM ? 16384 : 12288]
do_test 3.2 { file size test.db } 12288
do_test 3.3 { do_test 3.3 {
sqlite3 db1 test.db2 sqlite3 db1 test.db2

View File

@@ -75,6 +75,7 @@ do_test collate1-1.1 {
} }
} {{} 0x119 0x2D} } {{} 0x119 0x2D}
do_test collate1-1.2 { do_test collate1-1.2 {
breakpoint
execsql { execsql {
SELECT c2 FROM collate1t1 ORDER BY 1 COLLATE hex; SELECT c2 FROM collate1t1 ORDER BY 1 COLLATE hex;
} }

View File

@@ -168,7 +168,7 @@ foreach {tn sql temptables res} {
6 "b FROM t1" {hash} {b B} 6 "b FROM t1" {hash} {b B}
7 "a FROM t1" {} {A a} 7 "a FROM t1" {} {A a}
8 "b COLLATE nocase FROM t1" {} {b} 8 "b COLLATE nocase FROM t1" {} {b}
9 "b COLLATE nocase FROM t1 ORDER BY b COLLATE nocase" {} {B} 9 "b COLLATE nocase FROM t1 ORDER BY b COLLATE nocase" {} {b}
} { } {
do_execsql_test 2.$tn.1 "SELECT DISTINCT $sql" $res do_execsql_test 2.$tn.1 "SELECT DISTINCT $sql" $res
do_temptables_test 2.$tn.2 "SELECT DISTINCT $sql" $temptables do_temptables_test 2.$tn.2 "SELECT DISTINCT $sql" $temptables

View File

@@ -36,6 +36,12 @@ do_test filectrl-1.5 {
sqlite3 db test_control_lockproxy.db sqlite3 db test_control_lockproxy.db
file_control_lockproxy_test db [get_pwd] file_control_lockproxy_test db [get_pwd]
} {} } {}
do_test filectrl-1.6 {
sqlite3 db test.db
set fn [file_control_tempfilename db]
puts -nonewline \[$fn\]
set fn
} {/etilqs_/}
db close db close
forcedelete .test_control_lockproxy.db-conch test.proxy forcedelete .test_control_lockproxy.db-conch test.proxy
finish_test finish_test

View File

@@ -166,6 +166,8 @@ for {set i 1} {$i<$max_count-5} {incr i 1} {
} {1 interrupted} } {1 interrupted}
} }
if {0} { # This doesn't work anymore since the collation factor is
# no longer called during schema parsing.
# Interrupt during parsing # Interrupt during parsing
# #
do_test interrupt-5.1 { do_test interrupt-5.1 {
@@ -179,5 +181,5 @@ do_test interrupt-5.1 {
CREATE INDEX fake ON fake1(a COLLATE fake_collation, b, c DESC); CREATE INDEX fake ON fake1(a COLLATE fake_collation, b, c DESC);
} }
} {1 interrupt} } {1 interrupt}
}
finish_test finish_test

View File

@@ -27,6 +27,24 @@ if {!$MEMDEBUG} {
return return
} }
# Do not run these tests with an in-memory journal.
#
# In the pager layer, if an IO or OOM error occurs during a ROLLBACK, or
# when flushing a page to disk due to cache-stress, the pager enters an
# "error state". The only way out of the error state is to unlock the
# database file and end the transaction, leaving whatever journal and
# database files happen to be on disk in place. The next time the current
# (or any other) connection opens a read transaction, hot-journal rollback
# is performed if necessary.
#
# Of course, this doesn't work with an in-memory journal.
#
if {[permutation]=="inmemory_journal"} {
finish_test
return
}
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# NOTES ON RECOVERING FROM A MALLOC FAILURE # NOTES ON RECOVERING FROM A MALLOC FAILURE
# #
@@ -147,6 +165,7 @@ if {!$MEMDEBUG} {
# ::run_test_script. At the end of this file, the proc [run_test] is used # ::run_test_script. At the end of this file, the proc [run_test] is used
# to execute the program (and all test cases contained therein). # to execute the program (and all test cases contained therein).
# #
set ::run_test_sql_id 0
set ::run_test_script [list] set ::run_test_script [list]
proc TEST {id t} {lappend ::run_test_script -test [list $id $t]} proc TEST {id t} {lappend ::run_test_script -test [list $id $t]}
proc PREP {p} {lappend ::run_test_script -prep [string trim $p]} proc PREP {p} {lappend ::run_test_script -prep [string trim $p]}
@@ -162,13 +181,14 @@ proc DEBUG {s} {lappend ::run_test_script -debug $s}
# transaction only. # transaction only.
# #
proc SQL {a1 {a2 ""}} { proc SQL {a1 {a2 ""}} {
# An SQL primitive parameter is a list of two elements, a boolean value # An SQL primitive parameter is a list of three elements, an id, a boolean
# indicating if the statement may cause transaction rollback when malloc() # value indicating if the statement may cause transaction rollback when
# fails, and the sql statement itself. # malloc() fails, and the sql statement itself.
set id [incr ::run_test_sql_id]
if {$a2 == ""} { if {$a2 == ""} {
lappend ::run_test_script -sql [list true [string trim $a1]] lappend ::run_test_script -sql [list $id true [string trim $a1]]
} else { } else {
lappend ::run_test_script -sql [list false [string trim $a2]] lappend ::run_test_script -sql [list $id false [string trim $a2]]
} }
} }
@@ -258,7 +278,7 @@ TEST 5 {
set sql { set sql {
BEGIN;DELETE FROM abc; BEGIN;DELETE FROM abc;
} }
for {set i 1} {$i < 15} {incr i} { for {set i 1} {$i < 100} {incr i} {
set a $i set a $i
set b "String value $i" set b "String value $i"
set c [string repeat X $i] set c [string repeat X $i]
@@ -529,12 +549,13 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
} }
for {set i 0} {$i < $pcstart} {incr i} { for {set i 0} {$i < $pcstart} {incr i} {
set k2 [lindex $arglist [expr 2 * $i]] set k2 [lindex $arglist [expr {2 * $i}]]
set v2 [lindex $arglist [expr 2 * $i + 1]] set v2 [lindex $arglist [expr {2 * $i + 1}]]
set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit
switch -- $k2 { switch -- $k2 {
-sql {db eval [lindex $v2 1]} -sql {db eval [lindex $v2 2]}
-prep {db eval $v2} -prep {db eval $v2}
-debug {eval $v2}
} }
set nac [sqlite3_get_autocommit $::DB] ;# New Auto-Commit set nac [sqlite3_get_autocommit $::DB] ;# New Auto-Commit
if {$ac && !$nac} {set begin_pc $i} if {$ac && !$nac} {set begin_pc $i}
@@ -545,25 +566,31 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
set iFail $iFailStart set iFail $iFailStart
set pc $pcstart set pc $pcstart
while {$pc*2 < [llength $arglist]} { while {$pc*2 < [llength $arglist]} {
# Fetch the current instruction type and payload.
set k [lindex $arglist [expr {2 * $pc}]]
set v [lindex $arglist [expr {2 * $pc + 1}]]
# Id of this iteration: # Id of this iteration:
set k [lindex $arglist [expr 2 * $pc]]
set iterid "pc=$pc.iFail=$iFail$k" set iterid "pc=$pc.iFail=$iFail$k"
set v [lindex $arglist [expr 2 * $pc + 1]]
switch -- $k { switch -- $k {
-test { -test {
foreach {id script} $v {} foreach {id script} $v {}
set testid "malloc3-(test $id).$iterid"
eval $script
incr pc incr pc
} }
-sql { -sql {
set ::rollback_hook_count 0 set ::rollback_hook_count 0
set id [lindex $v 0]
set testid "malloc3-(integrity $id).$iterid"
set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit
sqlite3_memdebug_fail $iFail -repeat 0 sqlite3_memdebug_fail $iFail -repeat 0
set rc [catch {db eval [lindex $v 1]} msg] ;# True error occurs set rc [catch {db eval [lindex $v 2]} msg] ;# True error occurs
set nac [sqlite3_get_autocommit $::DB] ;# New Auto-Commit set nac [sqlite3_get_autocommit $::DB] ;# New Auto-Commit
if {$rc != 0 && $nac && !$ac} { if {$rc != 0 && $nac && !$ac} {
@@ -571,7 +598,7 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
# is set. Since an error occured we assume this was not a # is set. Since an error occured we assume this was not a
# commit - therefore a rollback occured. Check that the # commit - therefore a rollback occured. Check that the
# rollback-hook was invoked. # rollback-hook was invoked.
do_test malloc3-rollback_hook.$iterid { do_test malloc3-rollback_hook_count.$iterid {
set ::rollback_hook_count set ::rollback_hook_count
} {1} } {1}
} }
@@ -582,8 +609,9 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
# calls should be equal to the number of benign failures. # calls should be equal to the number of benign failures.
# Otherwise a malloc() failed and the error was not reported. # Otherwise a malloc() failed and the error was not reported.
# #
if {$nFail!=$nBenign} { set expr {$nFail!=$nBenign}
error "Unreported malloc() failure" if {[expr $expr]} {
error "Unreported malloc() failure, test \"$testid\", $expr"
} }
if {$ac && !$nac} { if {$ac && !$nac} {
@@ -595,24 +623,23 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
incr pc incr pc
set iFail 1 set iFail 1
integrity_check "malloc3-(integrity).$iterid" integrity_check $testid
} elseif {[regexp {.*out of memory} $msg] || [db errorcode] == 3082} { } elseif {[regexp {.*out of memory} $msg] || [db errorcode] == 3082} {
# Out of memory error, as expected. # Out of memory error, as expected.
# #
integrity_check "malloc3-(integrity).$iterid" integrity_check $testid
incr iFail incr iFail
if {$nac && !$ac} { if {$nac && !$ac} {
if {![lindex $v 1] && [db errorcode] != 3082} {
if {![lindex $v 0] && [db errorcode] != 3082} { # error "Statement \"[lindex $v 2]\" caused a rollback"
# error "Statement \"[lindex $v 1]\" caused a rollback"
} }
for {set i $begin_pc} {$i < $pc} {incr i} { for {set i $begin_pc} {$i < $pc} {incr i} {
set k2 [lindex $arglist [expr 2 * $i]] set k2 [lindex $arglist [expr {2 * $i}]]
set v2 [lindex $arglist [expr 2 * $i + 1]] set v2 [lindex $arglist [expr {2 * $i + 1}]]
set catchupsql "" set catchupsql ""
switch -- $k2 { switch -- $k2 {
-sql {set catchupsql [lindex $v2 1]} -sql {set catchupsql [lindex $v2 2]}
-prep {set catchupsql $v2} -prep {set catchupsql $v2}
} }
db eval $catchupsql db eval $catchupsql
@@ -622,7 +649,8 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
error $msg error $msg
} }
while {[lindex $arglist [expr 2 * ($pc -1)]] == "-test"} { # back up to the previous "-test" block.
while {[lindex $arglist [expr {2 * ($pc - 1)}]] == "-test"} {
incr pc -1 incr pc -1
} }
} }
@@ -642,7 +670,7 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
} }
} }
# Turn of the Tcl interface's prepared statement caching facility. Then # Turn off the Tcl interface's prepared statement caching facility. Then
# run the tests with "persistent" malloc failures. # run the tests with "persistent" malloc failures.
sqlite3_extended_result_codes db 1 sqlite3_extended_result_codes db 1
db cache size 0 db cache size 0

View File

@@ -136,6 +136,30 @@ do_test 2.4 {
set ::invoked_mycollate_db1 set ::invoked_mycollate_db1
} {0} } {0}
forcedelete test.db test.db2
sqlite3 db1 test.db
sqlite3 db2 test.db
db1 collate mycollate mycollate_db1
db2 collate mycollate mycollate_db2
do_test 2.13 {
set ::invoked_mycollate_db1 0
db1 eval {
CREATE TABLE t1(a, CHECK (a COLLATE mycollate IN ('one', 'two', 'three')));
INSERT INTO t1 VALUES('one');
}
db1 close
set ::invoked_mycollate_db1
} {1}
do_test 2.14 {
set ::invoked_mycollate_db1 0
db2 eval {
INSERT INTO t1 VALUES('two');
}
db2 close
set ::invoked_mycollate_db1
} {0}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# This test verifies that a bug causing a busy-handler belonging to one # This test verifies that a bug causing a busy-handler belonging to one
# shared-cache connection to be executed as a result of an sqlite3_step() # shared-cache connection to be executed as a result of an sqlite3_step()
@@ -204,4 +228,3 @@ db2 close
sqlite3_enable_shared_cache $::enable_shared_cache sqlite3_enable_shared_cache $::enable_shared_cache
finish_test finish_test

View File

@@ -401,6 +401,8 @@ do_malloc_test shared_err-8 -tclprep {
execsql {INSERT INTO t1 VALUES($a, $b)} db2 execsql {INSERT INTO t1 VALUES($a, $b)} db2
} }
execsql {COMMIT} db2 execsql {COMMIT} db2
execsql BEGIN
execsql ROLLBACK
set ::DB2 [sqlite3_connection_pointer db2] set ::DB2 [sqlite3_connection_pointer db2]
set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY] set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
sqlite3_step $::STMT ;# Cursor points at 0000000000 sqlite3_step $::STMT ;# Cursor points at 0000000000
@@ -409,8 +411,7 @@ do_malloc_test shared_err-8 -tclprep {
execsql { execsql {
BEGIN; BEGIN;
INSERT INTO t1 VALUES(6, NULL); INSERT INTO t1 VALUES(6, NULL);
ROLLBACK; ROLLBACK}
}
} -cleanup { } -cleanup {
# UPDATE: As of [5668], if the rollback fails SQLITE_CORRUPT is returned. # UPDATE: As of [5668], if the rollback fails SQLITE_CORRUPT is returned.
# So these tests have been updated to expect SQLITE_CORRUPT and its # So these tests have been updated to expect SQLITE_CORRUPT and its

View File

@@ -719,13 +719,14 @@ do_test shell1-3-29.1 {
do_test shell1-4.1 { do_test shell1-4.1 {
db eval { db eval {
CREATE TABLE t1(x); CREATE TABLE t1(x);
INSERT INTO t1 VALUES(null), (1), (2.25), ('hello'), (x'807f'); INSERT INTO t1 VALUES(null), (''), (1), (2.25), ('hello'), (x'807f');
} }
catchcmd test.db {.dump} catchcmd test.db {.dump}
} {0 {PRAGMA foreign_keys=OFF; } {0 {PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION; BEGIN TRANSACTION;
CREATE TABLE t1(x); CREATE TABLE t1(x);
INSERT INTO "t1" VALUES(NULL); INSERT INTO "t1" VALUES(NULL);
INSERT INTO "t1" VALUES('');
INSERT INTO "t1" VALUES(1); INSERT INTO "t1" VALUES(1);
INSERT INTO "t1" VALUES(2.25); INSERT INTO "t1" VALUES(2.25);
INSERT INTO "t1" VALUES('hello'); INSERT INTO "t1" VALUES('hello');
@@ -737,10 +738,58 @@ COMMIT;}}
do_test shell1-4.2 { do_test shell1-4.2 {
catchcmd test.db ".mode insert t1\nselect * from t1;" catchcmd test.db ".mode insert t1\nselect * from t1;"
} {0 {INSERT INTO t1 VALUES(NULL); } {0 {INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES('');
INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2.25); INSERT INTO t1 VALUES(2.25);
INSERT INTO t1 VALUES('hello'); INSERT INTO t1 VALUES('hello');
INSERT INTO t1 VALUES(X'807f');}} INSERT INTO t1 VALUES(X'807f');}}
# Test the output of ".mode tcl"
#
do_test shell1-4.3 {
catchcmd test.db ".mode tcl\nselect * from t1;"
} {0 {""
""
"1"
"2.25"
"hello"
"\200\177"}}
# Test the output of ".mode tcl" with multiple columns
#
do_test shell1-4.4 {
db eval {
CREATE TABLE t2(x,y);
INSERT INTO t2 VALUES(null, ''), (1, 2.25), ('hello', x'807f');
}
catchcmd test.db ".mode tcl\nselect * from t2;"
} {0 {"" ""
"1" "2.25"
"hello" "\200\177"}}
# Test the output of ".mode tcl" with ".nullvalue"
#
do_test shell1-4.5 {
catchcmd test.db ".mode tcl\n.nullvalue NULL\nselect * from t2;"
} {0 {"NULL" ""
"1" "2.25"
"hello" "\200\177"}}
# Test the output of ".mode tcl" with Tcl reserved characters
#
do_test shell1-4.6 {
db eval {
CREATE TABLE tcl1(x);
INSERT INTO tcl1 VALUES('"'), ('['), (']'), ('\{'), ('\}'), (';'), ('$');
}
foreach {x y} [catchcmd test.db ".mode tcl\nselect * from tcl1;"] break
list $x $y [llength $y]
} {0 {"\""
"["
"]"
"\\{"
"\\}"
";"
"$"} 7}
finish_test finish_test

View File

@@ -15,6 +15,7 @@
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
set ::testprefix subquery2
ifcapable !subquery { ifcapable !subquery {
finish_test finish_test
@@ -82,5 +83,25 @@ do_test subquery2-1.22 {
} }
} {1 3 5 7} } {1 3 5 7}
#-------------------------------------------------------------------------
# Test that ticket d6b36be38a has been fixed.
do_execsql_test 2.1 {
CREATE TABLE t4(a, b);
CREATE TABLE t5(a, b);
INSERT INTO t5 VALUES(3, 5);
INSERT INTO t4 VALUES(1, 1);
INSERT INTO t4 VALUES(2, 3);
INSERT INTO t4 VALUES(3, 6);
INSERT INTO t4 VALUES(4, 10);
INSERT INTO t4 VALUES(5, 15);
}
do_execsql_test 2.2 {
SELECT *
FROM (SELECT * FROM t4 ORDER BY a LIMIT -1 OFFSET 1)
LIMIT (SELECT a FROM t5)
} {2 3 3 6 4 10}
finish_test finish_test

View File

@@ -87,7 +87,7 @@ foreach {tn same_db shared_cache} [list \
do_test t1 { do_test t1 {
execsql { execsql {
SELECT SELECT
(SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) == (SELECT md5sum(a, b) FROM ab WHERE +a < (SELECT max(a) FROM ab)) ==
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab)) (SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
} }
} {1} } {1}
@@ -131,7 +131,7 @@ foreach {tn same_db shared_cache} [list \
do_test thread001.$tn.6 { do_test thread001.$tn.6 {
execsql { execsql {
SELECT SELECT
(SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) == (SELECT md5sum(a, b) FROM ab WHERE +a < (SELECT max(a) FROM ab)) ==
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab)) (SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
} }
} {1} } {1}

View File

@@ -273,11 +273,21 @@ do_test tkt2822-7.1 {
SELECT * FROM t7 ORDER BY 0; SELECT * FROM t7 ORDER BY 0;
} }
} {1 {1st ORDER BY term out of range - should be between 1 and 25}} } {1 {1st ORDER BY term out of range - should be between 1 and 25}}
do_test tkt2822-7.2 { do_test tkt2822-7.2.1 {
catchsql { catchsql {
SELECT * FROM t7 ORDER BY 1, 0; SELECT * FROM t7 ORDER BY 1, 0;
} }
} {1 {2nd ORDER BY term out of range - should be between 1 and 25}} } {1 {2nd ORDER BY term out of range - should be between 1 and 25}}
do_test tkt2822-7.2.2 {
catchsql {
SELECT * FROM t7 ORDER BY 1, 26;
}
} {1 {2nd ORDER BY term out of range - should be between 1 and 25}}
do_test tkt2822-7.2.3 {
catchsql {
SELECT * FROM t7 ORDER BY 1, 65536;
}
} {1 {2nd ORDER BY term out of range - should be between 1 and 25}}
do_test tkt2822-7.3 { do_test tkt2822-7.3 {
catchsql { catchsql {
SELECT * FROM t7 ORDER BY 1, 2, 0; SELECT * FROM t7 ORDER BY 1, 2, 0;

View File

@@ -949,6 +949,48 @@ do_catchsql_test triggerC-13.2 {
UPDATE t12 SET a=a+1, b=b+1; UPDATE t12 SET a=a+1, b=b+1;
} {1 {too many levels of trigger recursion}} } {1 {too many levels of trigger recursion}}
#-------------------------------------------------------------------------
# The following tests seek to verify that constant values (i.e. literals)
# are not factored out of loops within trigger programs. SQLite does
# not factor constants out of loops within trigger programs as it may only
# do so in code generated before the first table or index is opened. And
# by the time a trigger program is coded, at least one table or index has
# always been opened.
#
# At one point, due to a bug allowing constant factoring within triggers,
# the following SQL would produce the wrong result.
#
set SQL {
CREATE TABLE t1(a, b, c);
CREATE INDEX i1 ON t1(a, c);
CREATE INDEX i2 ON t1(b, c);
INSERT INTO t1 VALUES(1, 2, 3);
CREATE TABLE t2(e, f);
CREATE INDEX i3 ON t2(e);
INSERT INTO t2 VALUES(1234567, 3);
CREATE TABLE empty(x);
CREATE TABLE not_empty(x);
INSERT INTO not_empty VALUES(2);
CREATE TABLE t4(x);
CREATE TABLE t5(g, h, i);
CREATE TRIGGER trig BEFORE INSERT ON t4 BEGIN
INSERT INTO t5 SELECT * FROM t1 WHERE
(a IN (SELECT x FROM empty) OR b IN (SELECT x FROM not_empty))
AND c IN (SELECT f FROM t2 WHERE e=1234567);
END;
INSERT INTO t4 VALUES(0);
SELECT * FROM t5;
}
reset_db
do_execsql_test triggerC-14.1 $SQL {1 2 3}
reset_db
optimization_control db factor-constants 0
do_execsql_test triggerC-14.2 $SQL {1 2 3}
finish_test finish_test

View File

@@ -1293,4 +1293,44 @@ do_test 19.3 {
db2 close db2 close
} {} } {}
#-------------------------------------------------------------------------
# Test that the bug fixed by [b0c1ba655d69] really is fixed.
#
do_execsql_test 20.1 {
CREATE TABLE t7 (a, b);
CREATE TABLE t8 (c, d);
CREATE INDEX i2 ON t7(a);
CREATE INDEX i3 ON t7(b);
CREATE INDEX i4 ON t8(c);
CREATE INDEX i5 ON t8(d);
CREATE VIRTUAL TABLE t7v USING echo(t7);
CREATE VIRTUAL TABLE t8v USING echo(t8);
}
do_test 20.2 {
for {set i 0} {$i < 1000} {incr i} {
db eval {INSERT INTO t7 VALUES($i, $i)}
db eval {INSERT INTO t8 VALUES($i, $i)}
}
} {}
do_execsql_test 20.3 {
SELECT a, b FROM (
SELECT a, b FROM t7 WHERE a=11 OR b=12
UNION ALL
SELECT c, d FROM t8 WHERE c=5 OR d=6
)
ORDER BY 1, 2;
} {5 5 6 6 11 11 12 12}
do_execsql_test 20.4 {
SELECT a, b FROM (
SELECT a, b FROM t7v WHERE a=11 OR b=12
UNION ALL
SELECT c, d FROM t8v WHERE c=5 OR d=6
)
ORDER BY 1, 2;
} {5 5 6 6 11 11 12 12}
finish_test finish_test

View File

@@ -60,11 +60,16 @@ do_execsql_test 1.2 {
# Check file sizes are as expected. The real requirement here is that # Check file sizes are as expected. The real requirement here is that
# the *shm file is now more than one chunk (>32KiB). # the *shm file is now more than one chunk (>32KiB).
#
# The sizes of various files are slightly different in normal and
# auto-vacuum mode.
do_test 1.3 { file size test.db } {1024} do_test 1.3 { file size test.db } {1024}
do_test 1.4 { file size test.db-wal } {15421352} do_test 1.4 { expr {[file size test.db-wal]>(1500*1024)} } {1}
do_test 1.5 { expr {[file size test.db-shm]>32768} } {1} do_test 1.5 { expr {[file size test.db-shm]>32768} } {1}
do_test 1.6 {
do_execsql_test 1.6 { PRAGMA wal_checkpoint } {0 14715 14715} foreach {a b c} [db eval {PRAGMA wal_checkpoint}] break
list [expr {$a==0}] [expr {$b>14500}] [expr {$c>14500}] [expr {$b==$c}]
} {1 1 1 1}
# At this point connection [db2] has mapped the first 32KB of the *shm file # At this point connection [db2] has mapped the first 32KB of the *shm file
# only. Because the entire WAL file has been checkpointed, it is not # only. Because the entire WAL file has been checkpointed, it is not

View File

@@ -1079,6 +1079,7 @@ do_test where-13.12 {
# When optimizing out ORDER BY clauses, make sure that trailing terms # When optimizing out ORDER BY clauses, make sure that trailing terms
# of the ORDER BY clause do not reference other tables in a join. # of the ORDER BY clause do not reference other tables in a join.
# #
if {[permutation] != "no_optimization"} {
do_test where-14.1 { do_test where-14.1 {
execsql { execsql {
CREATE TABLE t8(a INTEGER PRIMARY KEY, b TEXT UNIQUE); CREATE TABLE t8(a INTEGER PRIMARY KEY, b TEXT UNIQUE);
@@ -1156,6 +1157,7 @@ do_test where-14.12 {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||x.b DESC SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||x.b DESC
} }
} {4/4 4/1 1/4 1/1 sort} } {4/4 4/1 1/4 1/1 sort}
} ;# {permutation != "no_optimization"}
# Ticket #2445. # Ticket #2445.
# #