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:
@@ -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
|
||||||
|
|||||||
@@ -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
1
configure
vendored
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
106
manifest
@@ -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
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ba8d08b67021a32fda069c18b7eb93523e6f0d1f
|
4f6d69ae94671df92b976525f75404c01270fef9
|
||||||
@@ -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)
|
||||||
|
|||||||
28
src/build.c
28
src/build.c
@@ -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 */
|
||||||
|
|||||||
174
src/expr.c
174
src/expr.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
29
src/insert.c
29
src/insert.c
@@ -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) */
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
11
src/os_win.c
11
src/os_win.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
src/parse.y
14
src/parse.y
@@ -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");
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/select.c
24
src/select.c
@@ -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);
|
||||||
|
|||||||
10
src/shell.c
10
src/shell.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 *);
|
||||||
|
|||||||
33
src/test1.c
33
src/test1.c
@@ -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 },
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
23
src/vdbe.c
23
src/vdbe.c
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
105
src/where.c
105
src/where.c
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user