1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +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.
#
LIBTCL = @TCL_LIB_SPEC@ @TCL_LIBS@
LIBTCL = @TCL_LIB_SPEC@
# Compiler options needed for programs that use the readline() library.
#
@@ -935,7 +935,6 @@ clean:
rm -rf .libs .deps
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
rm -f mkkeywordhash$(BEXE) keywordhash.h
rm -f $(PUBLISH)
rm -f *.da *.bb *.bbg gmon.out
rm -rf quota2a quota2b quota2c
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
$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl
sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl
$(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl
sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
# Rule to build the amalgamation
#

1
configure vendored
View File

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

View File

@@ -501,7 +501,6 @@ if test "${use_tcl}" = "yes" ; then
AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_BIN_DIR)
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_LIBS)
AC_SUBST(TCL_INCLUDE_SPEC)
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
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
in comments in sqlite3async.c.

View File

@@ -1510,6 +1510,7 @@ static void asyncWriterThread(void){
case ASYNC_DELETE:
ASYNC_TRACE(("DELETE %s\n", p->zBuf));
rc = pVfs->xDelete(pVfs, p->zBuf, (int)p->iOffset);
if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
break;
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
** 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
@@ -94,7 +94,7 @@ void sqlite3async_shutdown();
** If multiple simultaneous calls are made to sqlite3async_run() from two
** 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

View File

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

View File

@@ -127,6 +127,7 @@ void sqlite3FinishCoding(Parse *pParse){
sqlite3 *db;
Vdbe *v;
assert( pParse->pToplevel==0 );
db = pParse->db;
if( db->mallocFailed ) return;
if( pParse->nested ) return;
@@ -2690,10 +2691,8 @@ Index *sqlite3CreateIndex(
for(i=0; i<pList->nExpr; i++){
Expr *pExpr = pList->a[i].pExpr;
if( pExpr ){
CollSeq *pColl = pExpr->pColl;
/* Either pColl!=0 or there was an OOM failure. But if an OOM
** failure we have quit before reaching this point. */
if( ALWAYS(pColl) ){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
if( pColl ){
nExtra += (1 + sqlite3Strlen30(pColl->zName));
}
}
@@ -2756,6 +2755,7 @@ Index *sqlite3CreateIndex(
const char *zColName = pListItem->zName;
Column *pTabCol;
int requestedSortOrder;
CollSeq *pColl; /* Collating sequence */
char *zColl; /* Collation sequence name */
for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
@@ -2768,14 +2768,11 @@ Index *sqlite3CreateIndex(
goto exit_create_index;
}
pIndex->aiColumn[i] = j;
/* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
** the way the "idxlist" non-terminal is constructed by the parser,
** 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) ){
if( pListItem->pExpr
&& (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
){
int nColl;
zColl = pListItem->pExpr->pColl->zName;
zColl = pColl->zName;
nColl = sqlite3Strlen30(zColl) + 1;
assert( nExtra>=nColl );
memcpy(zExtra, zColl, nColl);
@@ -3589,6 +3586,15 @@ int sqlite3OpenTempDatabase(Parse *pParse){
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
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 ){
Vdbe *v = sqlite3GetVdbe(pToplevel);
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);
*/
char sqlite3ExprAffinity(Expr *pExpr){
int op = pExpr->op;
int op;
pExpr = sqlite3ExprSkipCollate(pExpr);
op = pExpr->op;
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
@@ -55,67 +57,95 @@ char sqlite3ExprAffinity(Expr *pExpr){
return pExpr->affinity;
}
/*
** Set the explicit collating sequence for an expression to the
** collating sequence supplied in the second argument.
*/
Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){
if( pExpr && pColl ){
pExpr->pColl = pColl;
pExpr->flags |= EP_ExpCollate;
}
return pExpr;
}
/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken. Return a pointer to the revised expression.
** The collating sequence is marked as "explicit" using the EP_ExpCollate
** flag. An explicit collating sequence will override implicit
** collating sequences.
** 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 *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){
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);
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
if( pCollName->n>0 ){
Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
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 the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
** Return the collation sequence for the expression pExpr. If
** there is no defined collating sequence, return NULL.
**
** The collating sequence might be determined by a COLLATE operator
** or by the presence of a column with a defined collating sequence.
** COLLATE operators take first precedence. Left operands take
** precedence over right operands.
*/
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
sqlite3 *db = pParse->db;
CollSeq *pColl = 0;
Expr *p = pExpr;
while( p ){
int op;
pColl = p->pColl;
if( pColl ) break;
op = p->op;
if( p->pTab!=0 && (
op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
)){
int op = p->op;
if( op==TK_CAST || op==TK_UPLUS ){
p = p->pLeft;
continue;
}
assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
if( op==TK_COLLATE ){
if( db->init.busy ){
/* Do not report errors when parsing while the schema */
pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0);
}else{
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
}
break;
}
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 */
const char *zColl;
int j = p->iColumn;
if( j>=0 ){
sqlite3 *db = pParse->db;
zColl = p->pTab->aCol[j].zColl;
const char *zColl = p->pTab->aCol[j].zColl;
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
pExpr->pColl = pColl;
}
break;
}
if( op!=TK_CAST && op!=TK_UPLUS ){
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;
}
}
if( sqlite3CheckCollSeq(pParse, pColl) ){
pColl = 0;
@@ -219,12 +249,10 @@ CollSeq *sqlite3BinaryCompareCollSeq(
){
CollSeq *pColl;
assert( pLeft );
if( pLeft->flags & EP_ExpCollate ){
assert( pLeft->pColl );
pColl = pLeft->pColl;
}else if( pRight && pRight->flags & EP_ExpCollate ){
assert( pRight->pColl );
pColl = pRight->pColl;
if( pLeft->flags & EP_Collate ){
pColl = sqlite3ExprCollSeq(pParse, pLeft);
}else if( pRight && (pRight->flags & EP_Collate)!=0 ){
pColl = sqlite3ExprCollSeq(pParse, pRight);
}else{
pColl = sqlite3ExprCollSeq(pParse, pLeft);
if( !pColl ){
@@ -454,17 +482,11 @@ void sqlite3ExprAttachSubtrees(
}else{
if( pRight ){
pRoot->pRight = pRight;
if( pRight->flags & EP_ExpCollate ){
pRoot->flags |= EP_ExpCollate;
pRoot->pColl = pRight->pColl;
}
pRoot->flags |= EP_Collate & pRight->flags;
}
if( pLeft ){
pRoot->pLeft = pLeft;
if( pLeft->flags & EP_ExpCollate ){
pRoot->flags |= EP_ExpCollate;
pRoot->pColl = pLeft->pColl;
}
pRoot->flags |= EP_Collate & pLeft->flags;
}
exprSetHeight(pRoot);
}
@@ -722,7 +744,7 @@ static int dupedExprStructSize(Expr *p, int flags){
assert( !ExprHasProperty(p, EP_FromJoin) );
assert( (p->flags2 & EP2_MallocedToken)==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;
}else{
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
@@ -2746,6 +2768,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
sqlite3ReleaseTempReg(pParse, r4);
break;
}
case TK_COLLATE:
case TK_UPLUS: {
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
break;
@@ -3115,6 +3138,12 @@ void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
case TK_ISNULL: zUniOp = "ISNULL"; 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_CONST_FUNC:
case TK_FUNCTION: {
@@ -3333,6 +3362,9 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
case TK_REGISTER: {
return WRC_Prune;
}
case TK_COLLATE: {
return WRC_Continue;
}
case TK_FUNCTION:
case TK_AGG_FUNCTION:
case TK_CONST_FUNC: {
@@ -3354,9 +3386,11 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
}
if( isAppropriateForFactoring(pExpr) ){
int r1 = ++pParse->nMem;
int r2;
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
/* If r2!=r1, it means that register r1 is never used. That is harmless
** 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->op = TK_REGISTER;
pExpr->iTable = r2;
@@ -3773,7 +3807,15 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
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->pRight, pB->pRight) ) 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){
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
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;
}

View File

@@ -511,12 +511,15 @@ static void fkScanChildren(
** expression to the parent key column defaults. */
if( pIdx ){
Column *pCol;
const char *zColl;
iCol = pIdx->aiColumn[i];
pCol = &pTab->aCol[iCol];
if( pTab->iPKey==iCol ) iCol = -1;
pLeft->iTable = regData+iCol+1;
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{
pLeft->iTable = regData;
pLeft->affinity = SQLITE_AFF_INTEGER;

View File

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

View File

@@ -25,7 +25,7 @@ void sqlite3OpenTable(
int opcode /* OP_OpenRead or OP_OpenWrite */
){
Vdbe *v;
if( IsVirtual(pTab) ) return;
assert( !IsVirtual(pTab) );
v = sqlite3GetVdbe(p);
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
@@ -1274,10 +1274,7 @@ void sqlite3GenerateConstraintChecks(
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
for(i=0; i<pCheck->nExpr; i++){
int allOk = sqlite3VdbeMakeLabel(v);
Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0);
if( !db->mallocFailed ){
assert( pDup!=0 );
sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL);
sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
if( onError==OE_Ignore ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
}else{
@@ -1292,8 +1289,6 @@ void sqlite3GenerateConstraintChecks(
}
sqlite3VdbeResolveLabel(v, allOk);
}
sqlite3ExprDelete(db, pDup);
}
}
#endif /* !defined(SQLITE_OMIT_CHECK) */

View File

@@ -228,6 +228,16 @@ int sqlite3JournalCreate(sqlite3_file *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
** 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.
*/
@@ -3618,6 +3621,14 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
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
/* The pager calls this method to signal that it has done
** 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.
*/
@@ -2751,6 +2754,14 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
}
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;
}

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
** 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
|| pPager->journalMode==PAGER_JOURNALMODE_MEMORY
|| pPager->journalMode==PAGER_JOURNALMODE_WAL
);
sqlite3OsClose(pPager->jfd);
if( !pPager->tempFile ){
if( bDelete ){
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
}
}
@@ -3485,7 +3486,7 @@ void sqlite3PagerSetBusyhandler(
void **ap = (void **)&pPager->xBusyHandler;
assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
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);
}
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.zEnd = &C.z[C.n];
}
@@ -1140,22 +1140,14 @@ uniqueflag(A) ::= . {A = OE_None;}
idxlist_opt(A) ::= . {A = 0;}
idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;}
idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). {
Expr *p = 0;
if( C.n>0 ){
p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
sqlite3ExprSetCollByToken(pParse, p, &C);
}
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
A = sqlite3ExprListAppend(pParse,X, p);
sqlite3ExprListSetName(pParse,A,&Y,1);
sqlite3ExprListCheckLength(pParse, A, "index");
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
}
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
Expr *p = 0;
if( C.n>0 ){
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
sqlite3ExprSetCollByToken(pParse, p, &C);
}
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
A = sqlite3ExprListAppend(pParse,0, p);
sqlite3ExprListSetName(pParse, A, &Y, 1);
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
** 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
** 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
@@ -91,8 +100,9 @@ static void resolveAlias(
assert( pOrig!=0 );
assert( pOrig->flags & EP_Resolved );
db = pParse->db;
if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
incrAggFunctionDepth(pDup, nSubquery);
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
if( pDup==0 ) return;
@@ -100,32 +110,26 @@ static void resolveAlias(
pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
}
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 ){
pDup->pColl = pExpr->pColl;
pDup->flags |= EP_ExpCollate;
if( pExpr->op==TK_COLLATE ){
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
}
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
** prevents ExprDelete() from deleting the Expr structure itself,
** 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);
sqlite3ExprDelete(db, 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);
}
@@ -812,7 +816,7 @@ static int resolveCompoundOrderBy(
int iCol = -1;
Expr *pE, *pDup;
if( pItem->done ) continue;
pE = pItem->pExpr;
pE = sqlite3ExprSkipCollate(pItem->pExpr);
if( sqlite3ExprIsInteger(pE, &iCol) ){
if( iCol<=0 || iCol>pEList->nExpr ){
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
@@ -830,14 +834,20 @@ static int resolveCompoundOrderBy(
}
}
if( iCol>0 ){
CollSeq *pColl = pE->pColl;
int flags = pE->flags & EP_ExpCollate;
/* Convert the ORDER BY term into an integer column number iCol,
** 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);
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->done = 1;
}else{
@@ -942,11 +952,11 @@ static int resolveOrderGroupBy(
pItem->iOrderByCol = (u16)iCol;
continue;
}
if( sqlite3ExprIsInteger(pE, &iCol) ){
if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
/* The ORDER BY term is an integer constant. Again, set the column
** number so that sqlite3ResolveOrderGroupBy() will convert the
** 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);
return 1;
}

View File

@@ -1335,7 +1335,7 @@ static int selectColumnsFromExprList(
for(i=0, pCol=aCol; i<nCol; i++, pCol++){
/* 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)
|| p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
if( (zName = pEList->a[i].zName)!=0 ){
@@ -2333,12 +2333,13 @@ static int multiSelectOrderBy(
for(i=0; i<nOrderBy; i++){
CollSeq *pColl;
Expr *pTerm = pOrderBy->a[i].pExpr;
if( pTerm->flags & EP_ExpCollate ){
pColl = pTerm->pColl;
if( pTerm->flags & EP_Collate ){
pColl = sqlite3ExprCollSeq(pParse, pTerm);
}else{
pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
pTerm->flags |= EP_ExpCollate;
pTerm->pColl = pColl;
if( pColl==0 ) pColl = db->pDfltColl;
pOrderBy->a[i].pExpr =
sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
}
pKeyMerge->aColl[i] = pColl;
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_Compare, destA.iSdst, destB.iSdst, nOrderBy,
(char*)pKeyMerge, P4_KEYINFO_HANDOFF);
sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
/* Release temporary registers
@@ -2608,9 +2610,6 @@ static Expr *substExpr(
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
if( pNew && pExpr->pColl ){
pNew->pColl = pExpr->pColl;
}
sqlite3ExprDelete(db, pExpr);
pExpr = pNew;
}
@@ -3950,6 +3949,15 @@ int sqlite3Select(
int addrEof;
pItem->regReturn = ++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);
addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor);
sqlite3VdbeChangeP5(v, 1);

View File

@@ -541,6 +541,9 @@ static void output_c_string(FILE *out, const char *z){
if( c=='\\' ){
fputc(c, out);
fputc(c, out);
}else if( c=='"' ){
fputc('\\', out);
fputc('"', out);
}else if( c=='\t' ){
fputc('\\', 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 ){
for(i=0; i<nArg; 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");
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
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");
break;
@@ -2018,6 +2021,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
p->mode = MODE_Html;
}else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
p->mode = MODE_Tcl;
sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
}else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
p->mode = MODE_Csv;
sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
@@ -2711,7 +2715,7 @@ static int process_input(struct callback_data *p, FILE *in){
free(zSql);
}
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]
** file control occurs at the beginning of pragma statement analysis and so
** it is able to override built-in [PRAGMA] statements.
** </ul>
**
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
** ^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
** should be retried. If it returns zero, the custom VFS should abandon the
** 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_GET_LOCKPROXYFILE 2
@@ -880,6 +889,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13
#define SQLITE_FCNTL_PRAGMA 14
#define SQLITE_FCNTL_BUSYHANDLER 15
#define SQLITE_FCNTL_TEMPFILENAME 16
/*
** CAPI3REF: Mutex Handle

View File

@@ -1158,19 +1158,7 @@ struct Column {
** structure. Conceptually, a collating sequence consists of a name and
** a comparison routine that defines the order of that sequence.
**
** There may two separate implementations of the collation function, one
** 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
** If CollSeq.xCmp is NULL, it means that the
** collating sequence is undefined. Indices built on an undefined
** collating sequence may not be read or written.
*/
@@ -1698,7 +1686,6 @@ struct Expr {
ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
} 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
** 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_DblQuoted 0x0040 /* token.z was originally in "..." */
#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_IntValue 0x0400 /* Integer value contained in u.iValue */
#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_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
#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
@@ -3046,8 +3034,9 @@ int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
Expr *sqlite3ExprSkipCollate(Expr*);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
@@ -3265,8 +3254,10 @@ int sqlite3FindInIndex(Parse *, Expr *, int*);
int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
int sqlite3JournalSize(sqlite3_vfs *);
int sqlite3JournalCreate(sqlite3_file *);
int sqlite3JournalExists(sqlite3_file *p);
#else
#define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
#define sqlite3JournalExists(p) 1
#endif
void sqlite3MemJournalOpen(sqlite3_file *);

View File

@@ -5321,6 +5321,38 @@ static int file_control_vfsname(
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
@@ -6150,6 +6182,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "file_control_persist_wal", file_control_persist_wal, 0 },
{ "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
{ "file_control_vfsname", file_control_vfsname, 0 },
{ "file_control_tempfilename", file_control_tempfilename, 0 },
{ "sqlite3_vfs_list", vfs_list, 0 },
{ "sqlite3_create_function_v2", test_create_function_v2, 0 },

View File

@@ -720,8 +720,8 @@ static int test_memdebug_settitle(
#ifdef SQLITE_MEMDEBUG
{
const char *zTitle;
zTitle = Tcl_GetString(objv[1]);
extern int sqlite3MemdebugSettitle(const char*);
zTitle = Tcl_GetString(objv[1]);
sqlite3MemdebugSettitle(zTitle);
}
#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().
*/
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);
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_OVERWRITE: zOp = "OVERWRITE"; break;
case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME"; break;
case 0xca093fa0: zOp = "DB_UNCHANGED"; break;
case SQLITE_FCNTL_PRAGMA: {
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",
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",
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;
/* 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 ){
case TK_UPDATE: {
sqlite3Update(pParse,

View File

@@ -432,7 +432,9 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
** Print the value of a register for tracing purposes:
*/
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");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
fprintf(out, " si:%lld", p->u.i);
@@ -1087,6 +1089,9 @@ case OP_Copy: {
while( 1 ){
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
Deephemeralize(pOut);
#ifdef SQLITE_DEBUG
pOut->pScopyFrom = 0;
#endif
REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
if( (n--)==0 ) break;
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
** of integers in P4.
**
** The permutation is only valid until the next OP_Permutation, OP_Compare,
** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur
** immediately prior to the OP_Compare.
** The permutation is only valid until the next OP_Compare that has
** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
** occur immediately prior to the OP_Compare.
*/
case OP_Permutation: {
assert( pOp->p4type==P4_INTARRAY );
@@ -1908,12 +1913,17 @@ case OP_Permutation: {
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
** 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.
**
** 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
** orders for the comparison. The permutation applies to registers
** only. The KeyInfo elements are used sequentially.
@@ -1932,6 +1942,7 @@ case OP_Compare: {
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
n = pOp->p3;
pKeyInfo = pOp->p4.pKeyInfo;
assert( n>0 );
@@ -3310,7 +3321,7 @@ case OP_OpenEphemeral: {
break;
}
/* Opcode: OpenSorter P1 P2 * P4 *
/* Opcode: SorterOpen P1 P2 * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** 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;
}
pOp = &p->aOp[addr];
assert( pOp->p4type==P4_NOTUSED || pOp->p4type==P4_INT32 );
freeP4(db, pOp->p4type, pOp->p4.p);
pOp->p4.p = 0;
if( n==P4_INT32 ){
@@ -866,8 +867,8 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
i = sqlite3Strlen30(zTemp);
for(j=0; j<pKeyInfo->nField; j++){
CollSeq *pColl = pKeyInfo->aColl[j];
if( pColl ){
int n = sqlite3Strlen30(pColl->zName);
const char *zColl = pColl ? pColl->zName : "nil";
int n = sqlite3Strlen30(zColl);
if( i+n>nTemp-6 ){
memcpy(&zTemp[i],",...",4);
break;
@@ -876,12 +877,8 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
if( pKeyInfo->aSortOrder[j] ){
zTemp[i++] = '-';
}
memcpy(&zTemp[i], pColl->zName,n+1);
memcpy(&zTemp[i], zColl, n+1);
i += n;
}else if( i+4<nTemp-6 ){
memcpy(&zTemp[i],",nil",4);
i += 4;
}
}
zTemp[i++] = ')';
zTemp[i] = 0;
@@ -2482,7 +2479,7 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
sqlite3DbFree(db, p->zSql);
sqlite3DbFree(db, p->pFree);
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
sqlite3DbFree(db, p->zExplain);
sqlite3_free(p->zExplain);
sqlite3DbFree(db, p->pExplain);
#endif
}

View File

@@ -563,23 +563,32 @@ static int allowedOp(int op){
** Commute a comparison operator. Expressions of the form "X op Y"
** 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
** 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
** 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.
*/
static void exprCommute(Parse *pParse, Expr *pExpr){
u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
u16 expRight = (pExpr->pRight->flags & EP_Collate);
u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;
pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;
if( expRight==expLeft ){
/* Either X and Y both have COLLATE operator or neither do */
if( expRight ){
/* Both X and Y have COLLATE operators. Make sure X is always
** 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);
if( pExpr->op>=TK_GT ){
assert( TK_LT==TK_GT+2 );
@@ -656,12 +665,12 @@ static WhereTerm *findTerm(
*/
assert(pX->pLeft);
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++){
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;
}
@@ -1179,7 +1188,7 @@ static void exprAnalyze(
}
pTerm = &pWC->a[idxTerm];
pMaskSet = pWC->pMaskSet;
pExpr = pTerm->pExpr;
pExpr = sqlite3ExprSkipCollate(pTerm->pExpr);
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
op = pExpr->op;
if( op==TK_IN ){
@@ -1206,8 +1215,8 @@ static void exprAnalyze(
pTerm->iParent = -1;
pTerm->eOperator = 0;
if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
if( pLeft->op==TK_COLUMN ){
pTerm->leftCursor = pLeft->iTable;
pTerm->u.leftColumn = pLeft->iColumn;
@@ -1235,7 +1244,7 @@ static void exprAnalyze(
pNew = pTerm;
}
exprCommute(pParse, pDup);
pLeft = pDup->pLeft;
pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
pNew->leftCursor = pLeft->iTable;
pNew->u.leftColumn = pLeft->iColumn;
testcase( (prereqLeft | extraRight) != prereqLeft );
@@ -1314,7 +1323,7 @@ static void exprAnalyze(
Expr *pNewExpr2;
int idxNew1;
int idxNew2;
CollSeq *pColl; /* Collating sequence to use */
Token sCollSeqName; /* Name of collating sequence */
pLeft = pExpr->x.pList->a[1].pExpr;
pStr2 = sqlite3ExprDup(db, pStr1, 0);
@@ -1336,15 +1345,18 @@ static void exprAnalyze(
}
*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,
sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
pStr1, 0);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew1==0 );
exprAnalyze(pSrc, pWC, idxNew1);
pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
pStr2, 0);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew2==0 );
@@ -1463,12 +1475,12 @@ static int findIndexCol(
const char *zColl = pIdx->azColl[iCol];
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
&& p->iColumn==pIdx->aiColumn[iCol]
&& p->iTable==iBase
){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, p);
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
return i;
}
@@ -1515,7 +1527,7 @@ static int isDistinctIndex(
*/
for(i=0; i<pDistinct->nExpr; i++){
WhereTerm *pTerm;
Expr *p = pDistinct->a[i].pExpr;
Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
if( p->op!=TK_COLUMN ) return 0;
pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
if( pTerm ){
@@ -1567,7 +1579,7 @@ static int isDistinctRedundant(
** current SELECT is a correlated sub-query.
*/
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;
}
@@ -2853,7 +2865,7 @@ static int isSortingIndex(
/* 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
** further use in handling the ORDER BY. */
pOBExpr = pOBItem->pExpr;
pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr);
if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
break;
}
@@ -2879,7 +2891,7 @@ static int isSortingIndex(
** clause entry. Set isMatch to 1 if they both match. */
if( pOBExpr->iColumn==iColumn ){
if( zColl ){
pColl = sqlite3ExprCollSeq(pParse, pOBExpr);
pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr);
if( !pColl ) pColl = db->pDfltColl;
isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
}else{
@@ -3020,6 +3032,11 @@ static void bestBtreeIndex(WhereBestIdx *p){
tRowcnt aiRowEstPk[2]; /* The aiRowEst[] 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 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 */
memset(&p->cost, 0, sizeof(p->cost));
@@ -3069,6 +3086,17 @@ static void bestBtreeIndex(WhereBestIdx *p){
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
*/
for(; pProbe; pIdx=pProbe=pProbe->pNext){
@@ -3146,11 +3174,9 @@ static void bestBtreeIndex(WhereBestIdx *p){
int nInMul = 1; /* Number of distinct equalities to lookup */
double rangeDiv = (double)1; /* Estimated reduction in search space */
int nBound = 0; /* Number of range constraints seen */
int bSort; /* True if external sort required */
int bDist; /* True if index cannot help with DISTINCT */
int bLookup = 0; /* True if not a covering index */
int nPriorSat; /* ORDER BY terms satisfied by outer loops */
int nOrderBy; /* Number of ORDER BY terms */
char bSort = bSortInit; /* True if external sort required */
char bDist = bDistInit; /* True if index cannot help with DISTINCT */
char bLookup = 0; /* True if not a covering index */
WhereTerm *pTerm; /* A single term of the WHERE clause */
#ifdef SQLITE_ENABLE_STAT3
WhereTerm *pFirstTerm = 0; /* First term matching the index */
@@ -3161,16 +3187,7 @@ static void bestBtreeIndex(WhereBestIdx *p){
pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
));
memset(&pc, 0, sizeof(pc));
nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
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;
}
pc.plan.nOBSat = nPriorSat;
/* Determine the values of pc.plan.nEq and nInMul */
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);
int iCur = pTabItem->iCursor;
sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
}else if( IsVirtual(pTab) ){
/* noop */
}else
#endif
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 INDEX i1 ON t1(a, b);
}
do_test 2.2 { file size test.db } 3072
do_test 2.2 { file size test.db } [expr $AUTOVACUUM ? 4096 : 3072]
do_test 2.3 {
sqlite3 db1 test.db2
@@ -90,8 +89,7 @@ do_execsql_test 3.1 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b);
}
do_test 3.2 { file size test.db } 12288
do_test 3.2 { file size test.db } [expr $AUTOVACUUM ? 16384 : 12288]
do_test 3.3 {
sqlite3 db1 test.db2

View File

@@ -75,6 +75,7 @@ do_test collate1-1.1 {
}
} {{} 0x119 0x2D}
do_test collate1-1.2 {
breakpoint
execsql {
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}
7 "a FROM t1" {} {A a}
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_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
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
forcedelete .test_control_lockproxy.db-conch test.proxy
finish_test

View File

@@ -166,6 +166,8 @@ for {set i 1} {$i<$max_count-5} {incr i 1} {
} {1 interrupted}
}
if {0} { # This doesn't work anymore since the collation factor is
# no longer called during schema parsing.
# Interrupt during parsing
#
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);
}
} {1 interrupt}
}
finish_test

View File

@@ -27,6 +27,24 @@ if {!$MEMDEBUG} {
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
#
@@ -147,6 +165,7 @@ if {!$MEMDEBUG} {
# ::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).
#
set ::run_test_sql_id 0
set ::run_test_script [list]
proc TEST {id t} {lappend ::run_test_script -test [list $id $t]}
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.
#
proc SQL {a1 {a2 ""}} {
# An SQL primitive parameter is a list of two elements, a boolean value
# indicating if the statement may cause transaction rollback when malloc()
# fails, and the sql statement itself.
# An SQL primitive parameter is a list of three elements, an id, a boolean
# value indicating if the statement may cause transaction rollback when
# malloc() fails, and the sql statement itself.
set id [incr ::run_test_sql_id]
if {$a2 == ""} {
lappend ::run_test_script -sql [list true [string trim $a1]]
lappend ::run_test_script -sql [list $id true [string trim $a1]]
} 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 {
BEGIN;DELETE FROM abc;
}
for {set i 1} {$i < 15} {incr i} {
for {set i 1} {$i < 100} {incr i} {
set a $i
set b "String value $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} {
set k2 [lindex $arglist [expr 2 * $i]]
set v2 [lindex $arglist [expr 2 * $i + 1]]
set k2 [lindex $arglist [expr {2 * $i}]]
set v2 [lindex $arglist [expr {2 * $i + 1}]]
set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit
switch -- $k2 {
-sql {db eval [lindex $v2 1]}
-sql {db eval [lindex $v2 2]}
-prep {db eval $v2}
-debug {eval $v2}
}
set nac [sqlite3_get_autocommit $::DB] ;# New Auto-Commit
if {$ac && !$nac} {set begin_pc $i}
@@ -545,25 +566,31 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
set iFail $iFailStart
set pc $pcstart
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:
set k [lindex $arglist [expr 2 * $pc]]
set iterid "pc=$pc.iFail=$iFail$k"
set v [lindex $arglist [expr 2 * $pc + 1]]
switch -- $k {
-test {
foreach {id script} $v {}
set testid "malloc3-(test $id).$iterid"
eval $script
incr pc
}
-sql {
set ::rollback_hook_count 0
set id [lindex $v 0]
set testid "malloc3-(integrity $id).$iterid"
set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit
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
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
# commit - therefore a rollback occured. Check that the
# rollback-hook was invoked.
do_test malloc3-rollback_hook.$iterid {
do_test malloc3-rollback_hook_count.$iterid {
set ::rollback_hook_count
} {1}
}
@@ -582,8 +609,9 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
# calls should be equal to the number of benign failures.
# Otherwise a malloc() failed and the error was not reported.
#
if {$nFail!=$nBenign} {
error "Unreported malloc() failure"
set expr {$nFail!=$nBenign}
if {[expr $expr]} {
error "Unreported malloc() failure, test \"$testid\", $expr"
}
if {$ac && !$nac} {
@@ -595,24 +623,23 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
incr pc
set iFail 1
integrity_check "malloc3-(integrity).$iterid"
integrity_check $testid
} elseif {[regexp {.*out of memory} $msg] || [db errorcode] == 3082} {
# Out of memory error, as expected.
#
integrity_check "malloc3-(integrity).$iterid"
integrity_check $testid
incr iFail
if {$nac && !$ac} {
if {![lindex $v 0] && [db errorcode] != 3082} {
# error "Statement \"[lindex $v 1]\" caused a rollback"
if {![lindex $v 1] && [db errorcode] != 3082} {
# error "Statement \"[lindex $v 2]\" caused a rollback"
}
for {set i $begin_pc} {$i < $pc} {incr i} {
set k2 [lindex $arglist [expr 2 * $i]]
set v2 [lindex $arglist [expr 2 * $i + 1]]
set k2 [lindex $arglist [expr {2 * $i}]]
set v2 [lindex $arglist [expr {2 * $i + 1}]]
set catchupsql ""
switch -- $k2 {
-sql {set catchupsql [lindex $v2 1]}
-sql {set catchupsql [lindex $v2 2]}
-prep {set catchupsql $v2}
}
db eval $catchupsql
@@ -622,7 +649,8 @@ proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
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
}
}
@@ -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.
sqlite3_extended_result_codes db 1
db cache size 0

View File

@@ -136,6 +136,30 @@ do_test 2.4 {
set ::invoked_mycollate_db1
} {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
# 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
finish_test

View File

@@ -401,6 +401,8 @@ do_malloc_test shared_err-8 -tclprep {
execsql {INSERT INTO t1 VALUES($a, $b)} db2
}
execsql {COMMIT} db2
execsql BEGIN
execsql ROLLBACK
set ::DB2 [sqlite3_connection_pointer db2]
set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
sqlite3_step $::STMT ;# Cursor points at 0000000000
@@ -409,8 +411,7 @@ do_malloc_test shared_err-8 -tclprep {
execsql {
BEGIN;
INSERT INTO t1 VALUES(6, NULL);
ROLLBACK;
}
ROLLBACK}
} -cleanup {
# UPDATE: As of [5668], if the rollback fails SQLITE_CORRUPT is returned.
# 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 {
db eval {
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}
} {0 {PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE t1(x);
INSERT INTO "t1" VALUES(NULL);
INSERT INTO "t1" VALUES('');
INSERT INTO "t1" VALUES(1);
INSERT INTO "t1" VALUES(2.25);
INSERT INTO "t1" VALUES('hello');
@@ -737,10 +738,58 @@ COMMIT;}}
do_test shell1-4.2 {
catchcmd test.db ".mode insert t1\nselect * from t1;"
} {0 {INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES('');
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2.25);
INSERT INTO t1 VALUES('hello');
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

View File

@@ -15,6 +15,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix subquery2
ifcapable !subquery {
finish_test
@@ -82,5 +83,25 @@ do_test subquery2-1.22 {
}
} {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

View File

@@ -87,7 +87,7 @@ foreach {tn same_db shared_cache} [list \
do_test t1 {
execsql {
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))
}
} {1}
@@ -131,7 +131,7 @@ foreach {tn same_db shared_cache} [list \
do_test thread001.$tn.6 {
execsql {
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))
}
} {1}

View File

@@ -273,11 +273,21 @@ do_test tkt2822-7.1 {
SELECT * FROM t7 ORDER BY 0;
}
} {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 {
SELECT * FROM t7 ORDER BY 1, 0;
}
} {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 {
catchsql {
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;
} {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

View File

@@ -1293,4 +1293,44 @@ do_test 19.3 {
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

View File

@@ -60,11 +60,16 @@ do_execsql_test 1.2 {
# Check file sizes are as expected. The real requirement here is that
# 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.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_execsql_test 1.6 { PRAGMA wal_checkpoint } {0 14715 14715}
do_test 1.6 {
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
# 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
# of the ORDER BY clause do not reference other tables in a join.
#
if {[permutation] != "no_optimization"} {
do_test where-14.1 {
execsql {
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
}
} {4/4 4/1 1/4 1/1 sort}
} ;# {permutation != "no_optimization"}
# Ticket #2445.
#