Compare commits

..

1 Commits

Author SHA1 Message Date
drh 426504965c Add a new OP_BColumn opcode where the cursor is guaranteed to be of type
CURTYPE_BTREE and is thus able to skip some checks and run slightly faster.

FossilOrigin-Name: 093e0d10a81adc078dcb3e08e33ce89bdbe53789
2015-11-21 17:53:06 +00:00
23 changed files with 130 additions and 481 deletions
+28 -26
View File
@@ -1,5 +1,5 @@
C Add\sthe\ssqlite3_strlike()\sinterface,\swhich\smight\sbe\suseful\sfor\simplementing\nLIKE\soperators\son\svirtual\stables.
D 2015-11-24T21:23:59.705
C Add\sa\snew\sOP_BColumn\sopcode\swhere\sthe\scursor\sis\sguaranteed\sto\sbe\sof\stype\nCURTYPE_BTREE\sand\sis\sthus\sable\sto\sskip\ssome\schecks\sand\srun\sslightly\sfaster.
D 2015-11-21T17:53:06.758
F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc e928e68168df69b353300ac87c10105206653a03
@@ -276,7 +276,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 9d649e46c780166e416fb11dbd23f8d49aab8267
F src/analyze.c 977bd50c751bb939ef52917892e12bedbfcea7ce
F src/analyze.c 4c308880cf53c558070cb8513bdff4ffb1a38a77
F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
@@ -292,10 +292,10 @@ F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da
F src/expr.c cb1a419508e5b27769a91e00e36e94724e7b1d51
F src/expr.c dfccb439a2a981d71970ce3d15effeb59b258798
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0
F src/func.c 5790a898a0c53e6787020ec268425d415e7e03c9
F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f
F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
@@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c 80ec49758dbce979e4f89eda7695bbc01b0c4cd3
F src/os_unix.c bddde71dc024574ace03ffee859abb99d152fd4a
F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e
@@ -339,11 +339,11 @@ F src/printf.c f8fc8f04e75b1e983ef2793c27ec7a43b287e94a
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c e10586c750d87211caa8f4b239e2bfa6a2049e5b
F src/select.c 0495e86f8377026fbd529a1a5bf62046cbb6eec5
F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c
F src/sqlite.h.in cbe8643b6a1c7313bf6447a2aa7abdb31c73dd77
F src/sqlite.h.in fa62718f73553f06b2f2e362fd09ccb4e1cbb626
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 41ef50b0418a7c5ad1337bb80db5a7928dee764f
F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
@@ -356,7 +356,7 @@ F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3
F src/test8.c 85b8c6a0309130300d560e2334ee71e70391785e
F src/test8.c 610e3d523018ca63b08081795e76794a2121ec38
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
@@ -389,7 +389,7 @@ F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b
F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
@@ -402,11 +402,11 @@ F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c b56b2fc9b2f2d0a99d1dbd02d47efaacec253a4c
F src/vdbe.c 8694c0e6497cd21e19e30ac059f933ac5d9abea2
F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637
F src/vdbeInt.h 75c2e82ee3357e9210c06474f8d9bdf12c81105d
F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
F src/vdbeaux.c 9a234c9aaab4ad725daf94667cfed441a437c52d
F src/vdbeaux.c 16e21a6ae0c290f17f6e7395d80686622cafeaa2
F src/vdbeblob.c fdc4a81605ae7a35ae94a55bd768b66d6be16f15
F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045
F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d
@@ -416,10 +416,10 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
F src/where.c 6687fb2675d9c1c1936ceca77529e2f21fb3a769
F src/whereInt.h 6afc0d70cf6213e58e8fbe10b6e50d1aa16f122f
F src/where.c 6aceb72cc58dc06922a9e1604d559c8ca4c3e728
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b
F src/whereexpr.c eebba8340c90de73b3d3bbe8c43b84559b8e6e2c
F src/whereexpr.c bd4877cd4dd11f6ab551ef0054535ca3c6224950
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -579,7 +579,7 @@ F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test a1783b960ad8c15a77cd9f207be072898db1026c
F test/distinct.test 175d49ee783febaf368192dfe7f5afbc68910230
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_blobbytes.test 9bea1d3e2b20f3010b04abba58f6ba172301f49f
F test/e_blobclose.test df756753f571bc30e42e3a6cba2807576e49e716
@@ -761,7 +761,7 @@ F test/fuzzdata4.db 1882f0055fb63214d8407ddc7aca9b0b1c59af21
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21
F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
@@ -1038,7 +1038,7 @@ F test/speedtest1.c f8bf04214e7b5f745feea99f7bde68b1c4870666
F test/spellfix.test 0597065ff57042df1f138e6a2611ae19c2698135
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
F test/sqllimits1.test 89b3d5aad05b99f707ee3786bdd4416dccf83304
F test/sqllog.test a8faa2df39610a037dd372ed872d124260d32953
F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
@@ -1051,7 +1051,7 @@ F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
F test/symlink.test 2513f7c030df0f435c6415687ba8b739f3d312df
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
F test/syscall.test 2aa9e111b79fb385681ff8940124def6f8faab87
F test/syscall.test fba9ebdc6905d05bba6a835e691f20ed9ea2cc88
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
F test/tabfunc01.test cc33684f9480fcf1fd5ce287ac28d22971cad1cc
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
@@ -1259,7 +1259,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9
F test/vtab1.test ec5cb767277d7e0eff34d3a02824c1dd959a5959
F test/vtab1.test 6210e076997f176bedc300a87ad6404651b601dd
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
@@ -1272,9 +1272,8 @@ F test/vtabA.test 1317f06a03597eee29f40a49b6c21e1aaba4285f
F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796
F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe
F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61
F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
F test/vtabH.test 694aa399eb28ed0db2aef59f2f37532781eeb957
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772
@@ -1405,7 +1404,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 069e51b19c773aa3017a8d307c8daa0766c224ba
R d30ed8c32e99c9a94479405580943fff
P 198d191b2f5ef7d63ac0093c701955c9052fd734
R 047e676af06478b15f87435c78af3c91
T *branch * btree-column-opcode
T *sym-btree-column-opcode *
T -sym-trunk *
U drh
Z d8529710de4140b85add41abcb0a95e1
Z d7290cc1ec32ea2c40df94d6965d7340
+1 -1
View File
@@ -1 +1 @@
e70ec71d6883f2f8fc75301ff985bccb5aa06127
093e0d10a81adc078dcb3e08e33ce89bdbe53789
+1 -1
View File
@@ -990,7 +990,7 @@ static void analyzeOneTable(
/* Do not gather statistics on views or virtual tables */
return;
}
if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){
if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==0 ){
/* Do not gather statistics on system tables */
return;
}
+1 -1
View File
@@ -3818,7 +3818,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
}
return 2;
}
if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken ){
if( pA->op==TK_FUNCTION ){
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
}else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
-7
View File
@@ -763,13 +763,6 @@ int sqlite3_strglob(const char *zGlobPattern, const char *zString){
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
}
/*
** The sqlite3_strlike() interface.
*/
int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc)==0;
}
/*
** Count the number of times that the LIKE operator (or GLOB which is
** just a variation of LIKE) gets called. This is used for testing
+35 -30
View File
@@ -258,7 +258,8 @@ static pid_t randomnessPid = 0;
#define UNIXFILE_DELETE 0x20 /* Delete on close */
#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
#define UNIXFILE_BLOCK 0x0100 /* Next SHM lock might block */
#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings issued */
#define UNIXFILE_BLOCK 0x0200 /* Next SHM lock might block */
/*
** Include code that is common to all os_*.c files
@@ -323,6 +324,19 @@ static int posixOpen(const char *zFile, int flags, int mode){
return open(zFile, flags, mode);
}
/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes. So avoid calling fchown() if
** we are not running as root.
*/
static int posixFchown(int fd, uid_t uid, gid_t gid){
#if OS_VXWORKS
return 0;
#else
return geteuid() ? 0 : fchown(fd,uid,gid);
#endif
}
/* Forward reference */
static int openDirectory(const char*, int*);
static int unixGetpagesize(void);
@@ -409,7 +423,7 @@ static struct unix_syscall {
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
aSyscall[13].pCurrent)
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
@@ -431,50 +445,32 @@ static struct unix_syscall {
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
{ "fchown", (sqlite3_syscall_ptr)fchown, 0 },
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
{ "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
{ "mmap", (sqlite3_syscall_ptr)mmap, 0 },
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)
{ "munmap", (sqlite3_syscall_ptr)munmap, 0 },
#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
#if HAVE_MREMAP
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
#else
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
#endif
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent)
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent)
#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
{ "readlink", (sqlite3_syscall_ptr)readlink, 0 },
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[25].pCurrent)
#endif
}; /* End of the overrideable system calls */
/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes. So avoid calling fchown() if
** we are not running as root.
*/
static int robustFchown(int fd, uid_t uid, gid_t gid){
#if OS_VXWORKS
return 0;
#else
return osGeteuid() ? 0 : osFchown(fd,uid,gid);
#endif
}
/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "unix" VFSes. Return SQLITE_OK opon successfully updating the
@@ -1103,7 +1099,7 @@ static unixInodeInfo *inodeList = 0;
/*
**
** This function - unixLogErrorAtLine(), is only ever called via the macro
** This function - unixLogError_x(), is only ever called via the macro
** unixLogError().
**
** It is invoked after an error occurs in an OS function and errno has been
@@ -1359,21 +1355,30 @@ static int fileHasMoved(unixFile *pFile){
static void verifyDbFile(unixFile *pFile){
struct stat buf;
int rc;
if( pFile->ctrlFlags & UNIXFILE_WARNED ){
/* One or more of the following warnings have already been issued. Do not
** repeat them so as not to clutter the error log */
return;
}
rc = osFstat(pFile->h, &buf);
if( rc!=0 ){
sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
if( buf.st_nlink>1 ){
sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
if( fileHasMoved(pFile) ){
sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
}
@@ -4338,7 +4343,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** is owned by the same user that owns the original database. Otherwise,
** the original owner will not be able to connect.
*/
robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
/* Check to see if another process is holding the dead-man switch.
** If not, truncate the file to zero length.
@@ -5822,7 +5827,7 @@ static int unixOpen(
** the same as the original database.
*/
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
robustFchown(fd, uid, gid);
osFchown(fd, uid, gid);
}
}
assert( fd>=0 );
@@ -7579,7 +7584,7 @@ int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==27 );
assert( ArraySize(aSyscall)==26 );
/* Register all VFSes defined in the aVfs[] array */
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
-2
View File
@@ -1613,7 +1613,6 @@ int sqlite3ColumnsFromExprList(
nCol = 0;
aCol = 0;
}
assert( nCol==(i16)nCol );
*pnCol = nCol;
*paCol = aCol;
@@ -4456,7 +4455,6 @@ static int selectExpander(Walker *pWalker, Select *p){
#if SQLITE_MAX_COLUMN
if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite3ErrorMsg(pParse, "too many columns in result set");
return WRC_Abort;
}
#endif
return WRC_Continue;
+6 -36
View File
@@ -5709,15 +5709,12 @@ struct sqlite3_index_info {
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
*/
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
#define SQLITE_INDEX_CONSTRAINT_LE 8
#define SQLITE_INDEX_CONSTRAINT_LT 16
#define SQLITE_INDEX_CONSTRAINT_GE 32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
#define SQLITE_INDEX_CONSTRAINT_LIKE 65
#define SQLITE_INDEX_CONSTRAINT_GLOB 66
#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
#define SQLITE_INDEX_CONSTRAINT_LE 8
#define SQLITE_INDEX_CONSTRAINT_LT 16
#define SQLITE_INDEX_CONSTRAINT_GE 32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
/*
** CAPI3REF: Register A Virtual Table Implementation
@@ -7377,36 +7374,9 @@ int sqlite3_strnicmp(const char *, const char *, int);
**
** Note that this routine returns zero on a match and non-zero if the strings
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
**
** See also: sqlite3_strlike().
*/
int sqlite3_strglob(const char *zGlob, const char *zStr);
/*
** CAPI3REF: String LIKE Matching
*
** ^The [sqlite3_strlike(P,X,E)] interface returns zero if string X matches
** the LIKE pattern P with escape character E, and it returns non-zero if
** string X does not match the like pattern.
** ^The definition of LIKE pattern matching used in
** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
** operator in the SQL dialect used by SQLite. ^For "X LIKE P" without
** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
** ^As with the LIKE operator, the [sqlite3_str(P,X,E)] function is case
** insensitive - equivalent upper and lower case ASCII characters match
** one another.
**
** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
** only ASCII characters are case folded. (This is because when SQLite was
** first written, the case folding rules for Unicode where still in flux.)
**
** Note that this routine returns zero on a match and non-zero if the strings
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
**
** See also: sqlite3_strglob().
*/
int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
/*
** CAPI3REF: Error Logging Interface
**
-4
View File
@@ -275,8 +275,6 @@ struct sqlite3_api_routines {
/* Version 3.9.0 and later */
unsigned int (*value_subtype)(sqlite3_value*);
void (*result_subtype)(sqlite3_context*,unsigned int);
/* Version 3.10.0 and later */
int (*strlike)(const char*,const char*,unsigned int);
};
/*
@@ -516,8 +514,6 @@ struct sqlite3_api_routines {
/* Version 3.9.0 and later */
#define sqlite3_value_subtype sqlite3_api->value_subtype
#define sqlite3_result_subtype sqlite3_api->result_subtype
/* Version 3.10.0 and later */
#define sqlite3_strlike sqlite3_api->strlike
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
-13
View File
@@ -848,20 +848,7 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
case SQLITE_INDEX_CONSTRAINT_GE:
zOp = ">="; break;
case SQLITE_INDEX_CONSTRAINT_MATCH:
/* Purposely translate the MATCH operator into a LIKE, which
** will be used by the next block of code to construct a new
** query. It should also be noted here that the next block
** of code requires the first letter of this operator to be
** in upper-case to trigger the special MATCH handling (i.e.
** wrapping the bound parameter with literal '%'s).
*/
zOp = "LIKE"; break;
case SQLITE_INDEX_CONSTRAINT_LIKE:
zOp = "like"; break;
case SQLITE_INDEX_CONSTRAINT_GLOB:
zOp = "glob"; break;
case SQLITE_INDEX_CONSTRAINT_REGEXP:
zOp = "regexp"; break;
}
if( zOp[0]=='L' ){
zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')",
+28 -168
View File
@@ -23,15 +23,6 @@
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Characters that make up the idxStr created by xBestIndex for xFilter.
*/
#define TCLVAR_NAME_EQ 'e'
#define TCLVAR_NAME_MATCH 'm'
#define TCLVAR_VALUE_GLOB 'g'
#define TCLVAR_VALUE_REGEXP 'r'
#define TCLVAR_VALUE_LIKE 'l'
typedef struct tclvar_vtab tclvar_vtab;
typedef struct tclvar_cursor tclvar_cursor;
@@ -164,44 +155,15 @@ static int tclvarFilter(
){
tclvar_cursor *pCur = (tclvar_cursor *)pVtabCursor;
Tcl_Interp *interp = ((tclvar_vtab *)(pVtabCursor->pVtab))->interp;
Tcl_Obj *p = Tcl_NewStringObj("tclvar_filter_cmd", -1);
const char *zEq = "";
const char *zMatch = "";
const char *zGlob = "";
const char *zRegexp = "";
const char *zLike = "";
int i;
for(i=0; idxStr[i]; i++){
switch( idxStr[i] ){
case TCLVAR_NAME_EQ:
zEq = (const char*)sqlite3_value_text(argv[i]);
break;
case TCLVAR_NAME_MATCH:
zMatch = (const char*)sqlite3_value_text(argv[i]);
break;
case TCLVAR_VALUE_GLOB:
zGlob = (const char*)sqlite3_value_text(argv[i]);
break;
case TCLVAR_VALUE_REGEXP:
zRegexp = (const char*)sqlite3_value_text(argv[i]);
break;
case TCLVAR_VALUE_LIKE:
zLike = (const char*)sqlite3_value_text(argv[i]);
break;
default:
assert( 0 );
}
}
Tcl_Obj *p = Tcl_NewStringObj("info vars", -1);
Tcl_IncrRefCount(p);
Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zEq, -1));
Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zMatch, -1));
Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zGlob, -1));
Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zRegexp, -1));
Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zLike, -1));
assert( argc==0 || argc==1 );
if( argc==1 ){
Tcl_Obj *pArg = Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1);
Tcl_ListObjAppendElement(0, p, pArg);
}
Tcl_EvalObjEx(interp, p, TCL_EVAL_GLOBAL);
if( pCur->pList1 ){
Tcl_DecrRefCount(pCur->pList1);
@@ -214,6 +176,7 @@ static int tclvarFilter(
pCur->i2 = 0;
pCur->pList1 = Tcl_GetObjResult(interp);
Tcl_IncrRefCount(pCur->pList1);
assert( pCur->i1==0 && pCur->i2==0 && pCur->pList2==0 );
Tcl_DecrRefCount(p);
return tclvarNext(pVtabCursor);
@@ -261,113 +224,32 @@ static int tclvarEof(sqlite3_vtab_cursor *cur){
return (pCur->pList2?0:1);
}
/*
** If nul-terminated string zStr does not already contain the character
** passed as the second argument, append it and return 0. Or, if there is
** already an instance of x in zStr, do nothing return 1;
**
** There is guaranteed to be enough room in the buffer pointed to by zStr
** for the new character and nul-terminator.
*/
static int tclvarAddToIdxstr(char *zStr, char x){
int i;
for(i=0; zStr[i]; i++){
if( zStr[i]==x ) return 1;
}
zStr[i] = x;
zStr[i+1] = '\0';
return 0;
}
/*
** Return true if variable $::tclvar_set_omit exists and is set to true.
** False otherwise.
*/
static int tclvarSetOmit(Tcl_Interp *interp){
int rc;
int res = 0;
Tcl_Obj *pRes;
rc = Tcl_Eval(interp,
"expr {[info exists ::tclvar_set_omit] && $::tclvar_set_omit}"
);
if( rc==TCL_OK ){
pRes = Tcl_GetObjResult(interp);
rc = Tcl_GetBooleanFromObj(0, pRes, &res);
}
return (rc==TCL_OK && res);
}
/*
** The xBestIndex() method. This virtual table supports the following
** operators:
**
** name = ? (omit flag clear)
** name MATCH ? (omit flag set)
** value GLOB ? (omit flag set iff $::tclvar_set_omit)
** value REGEXP ? (omit flag set iff $::tclvar_set_omit)
** value LIKE ? (omit flag set iff $::tclvar_set_omit)
**
** For each constraint present, the corresponding TCLVAR_XXX character is
** appended to the idxStr value.
*/
static int tclvarBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
tclvar_vtab *pTab = (tclvar_vtab*)tab;
int ii;
char *zStr = sqlite3_malloc(32);
int iStr = 0;
if( zStr==0 ) return SQLITE_NOMEM;
zStr[0] = '\0';
for(ii=0; ii<pIdxInfo->nConstraint; ii++){
struct sqlite3_index_constraint const *pCons = &pIdxInfo->aConstraint[ii];
struct sqlite3_index_constraint_usage *pUsage;
pUsage = &pIdxInfo->aConstraintUsage[ii];
if( pCons->usable ){
/* name = ? */
if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && pCons->iColumn==0 ){
if( 0==tclvarAddToIdxstr(zStr, TCLVAR_NAME_EQ) ){
pUsage->argvIndex = ++iStr;
pUsage->omit = 0;
}
}
/* name MATCH ? */
if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH && pCons->iColumn==0 ){
if( 0==tclvarAddToIdxstr(zStr, TCLVAR_NAME_MATCH) ){
pUsage->argvIndex = ++iStr;
pUsage->omit = 1;
}
}
/* value GLOB ? */
if( pCons->op==SQLITE_INDEX_CONSTRAINT_GLOB && pCons->iColumn==2 ){
if( 0==tclvarAddToIdxstr(zStr, TCLVAR_VALUE_GLOB) ){
pUsage->argvIndex = ++iStr;
pUsage->omit = tclvarSetOmit(pTab->interp);
}
}
/* value REGEXP ? */
if( pCons->op==SQLITE_INDEX_CONSTRAINT_REGEXP && pCons->iColumn==2 ){
if( 0==tclvarAddToIdxstr(zStr, TCLVAR_VALUE_REGEXP) ){
pUsage->argvIndex = ++iStr;
pUsage->omit = tclvarSetOmit(pTab->interp);
}
}
/* value LIKE ? */
if( pCons->op==SQLITE_INDEX_CONSTRAINT_LIKE && pCons->iColumn==2 ){
if( 0==tclvarAddToIdxstr(zStr, TCLVAR_VALUE_LIKE) ){
pUsage->argvIndex = ++iStr;
pUsage->omit = tclvarSetOmit(pTab->interp);
}
}
if( pCons->iColumn==0 && pCons->usable
&& pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
struct sqlite3_index_constraint_usage *pUsage;
pUsage = &pIdxInfo->aConstraintUsage[ii];
pUsage->omit = 0;
pUsage->argvIndex = 1;
return SQLITE_OK;
}
}
for(ii=0; ii<pIdxInfo->nConstraint; ii++){
struct sqlite3_index_constraint const *pCons = &pIdxInfo->aConstraint[ii];
if( pCons->iColumn==0 && pCons->usable
&& pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){
struct sqlite3_index_constraint_usage *pUsage;
pUsage = &pIdxInfo->aConstraintUsage[ii];
pUsage->omit = 1;
pUsage->argvIndex = 1;
return SQLITE_OK;
}
}
pIdxInfo->idxStr = zStr;
pIdxInfo->needToFreeIdxStr = 1;
return SQLITE_OK;
}
@@ -413,7 +295,6 @@ static int register_tclvar_module(
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
int rc = TCL_OK;
sqlite3 *db;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
@@ -421,30 +302,9 @@ static int register_tclvar_module(
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_create_module(db, "tclvar", &tclvarModule, (void*)interp);
rc = Tcl_Eval(interp,
"proc like {pattern str} {\n"
" set p [string map {% * _ ?} $pattern]\n"
" string match $p $str\n"
"}\n"
"proc tclvar_filter_cmd {eq match glob regexp like} {\n"
" set res {}\n"
" set pattern $eq\n"
" if {$pattern=={}} { set pattern $match }\n"
" if {$pattern=={}} { set pattern * }\n"
" foreach v [uplevel #0 info vars $pattern] {\n"
" if {($glob=={} || [string match $glob [uplevel #0 set $v]])\n"
" && ($like=={} || [like $like [uplevel #0 set $v]])\n"
" && ($regexp=={} || [regexp $regexp [uplevel #0 set $v]])\n"
" } {\n"
" lappend res $v\n"
" }\n"
" }\n"
" set res\n"
"}\n"
);
sqlite3_create_module(db, "tclvar", &tclvarModule, (void *)interp);
#endif
return rc;
return TCL_OK;
}
#endif
+9 -3
View File
@@ -2375,12 +2375,20 @@ case OP_Column: {
u16 fx; /* pDest->flags value */
Mem *pReg; /* PseudoTable input register */
pC = p->apCsr[pOp->p1];
if( pC->eCurType==CURTYPE_PSEUDO ) goto skip_moveto;
pOp->opcode = OP_BColumn;
case OP_BColumn:
pC = p->apCsr[pOp->p1];
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
skip_moveto:
p2 = pOp->p2;
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
pDest = &aMem[pOp->p3];
memAboutToChange(p, pDest);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( p2<pC->nField );
aOffset = pC->aOffset;
@@ -2390,8 +2398,6 @@ case OP_Column: {
pCrsr = pC->uc.pCursor;
/* If the cursor cache is stale, bring it up-to-date */
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
if( pC->cacheStatus!=p->cacheCtr ){
if( pC->nullRow ){
if( pC->eCurType==CURTYPE_PSEUDO ){
+7 -7
View File
@@ -837,6 +837,7 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
freeP4(db, pOp->p4type, pOp->p4.p);
memset(pOp, 0, sizeof(pOp[0]));
pOp->opcode = OP_Noop;
if( addr==p->nOp-1 ) p->nOp--;
}
}
@@ -2999,13 +3000,12 @@ int sqlite3VdbeCursorRestore(VdbeCursor *p){
** not been deleted out from under the cursor, then this routine is a no-op.
*/
int sqlite3VdbeCursorMoveto(VdbeCursor *p){
if( p->eCurType==CURTYPE_BTREE ){
if( p->deferredMoveto ){
return handleDeferredMoveto(p);
}
if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
return handleMovedCursor(p);
}
assert( p->eCurType==CURTYPE_BTREE );
if( p->deferredMoveto ){
return handleDeferredMoveto(p);
}
if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
return handleMovedCursor(p);
}
return SQLITE_OK;
}
-3
View File
@@ -893,9 +893,6 @@ static sqlite3_index_info *allocateIndexInfo(
pIdxCons[j].iTermOffset = i;
op = (u8)pTerm->eOperator & WO_ALL;
if( op==WO_IN ) op = WO_EQ;
if( op==WO_MATCH ){
op = pTerm->eMatchOp;
}
pIdxCons[j].op = op;
/* The direct assignment in the previous line is possible only because
** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
-1
View File
@@ -253,7 +253,6 @@ struct WhereTerm {
u16 eOperator; /* A WO_xx value describing <op> */
u16 wtFlags; /* TERM_xxx bit flags. See below */
u8 nChild; /* Number of children that must disable us */
u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
WhereClause *pWC; /* The clause this term is part of */
Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
+9 -30
View File
@@ -277,48 +277,29 @@ static int isLikeOrGlob(
/*
** Check to see if the given expression is of the form
**
** column OP expr
**
** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a
** column of a virtual table.
** column MATCH expr
**
** If it is then return TRUE. If not, return FALSE.
*/
static int isMatchOfColumn(
Expr *pExpr, /* Test this expression */
unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */
Expr *pExpr /* Test this expression */
){
struct Op2 {
const char *zOp;
unsigned char eOp2;
} aOp[] = {
{ "match", SQLITE_INDEX_CONSTRAINT_MATCH },
{ "glob", SQLITE_INDEX_CONSTRAINT_GLOB },
{ "like", SQLITE_INDEX_CONSTRAINT_LIKE },
{ "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
};
ExprList *pList;
Expr *pCol; /* Column reference */
int i;
if( pExpr->op!=TK_FUNCTION ){
return 0;
}
if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){
return 0;
}
pList = pExpr->x.pList;
if( pList==0 || pList->nExpr!=2 ){
if( pList->nExpr!=2 ){
return 0;
}
pCol = pList->a[1].pExpr;
if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
if( pList->a[1].pExpr->op != TK_COLUMN ){
return 0;
}
for(i=0; i<ArraySize(aOp); i++){
if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
*peOp2 = aOp[i].eOp2;
return 1;
}
}
return 0;
return 1;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -895,7 +876,6 @@ static void exprAnalyze(
int op; /* Top-level operator. pExpr->op */
Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection */
unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */
if( db->mallocFailed ){
return;
@@ -1119,7 +1099,7 @@ static void exprAnalyze(
** virtual tables. The native query optimizer does not attempt
** to do anything with MATCH functions.
*/
if( isMatchOfColumn(pExpr, &eOp2) ){
if( isMatchOfColumn(pExpr) ){
int idxNew;
Expr *pRight, *pLeft;
WhereTerm *pNewTerm;
@@ -1140,7 +1120,6 @@ static void exprAnalyze(
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_MATCH;
pNewTerm->eMatchOp = eOp2;
markTermAsChild(pWC, idxNew, idxTerm);
pTerm = &pWC->a[idxTerm];
pTerm->wtFlags |= TERM_COPIED;
-17
View File
@@ -252,21 +252,4 @@ do_execsql_test 5.6 {
SELECT DISTINCT x FROM t1 ORDER BY x;
} {1 2 3 4 5 6}
#-------------------------------------------------------------------------
# 2015-11-23. Problem discovered by Kostya Serebryany using libFuzzer
#
db close
sqlite3 db :memory:
do_execsql_test 6.1 {
CREATE TABLE jjj(x);
SELECT (SELECT 'mmm' UNION SELECT DISTINCT max(name) ORDER BY 1)
FROM sqlite_master;
} {jjj}
do_execsql_test 6.2 {
CREATE TABLE nnn(x);
SELECT (SELECT 'mmm' UNION SELECT DISTINCT max(name) ORDER BY 1)
FROM sqlite_master;
} {mmm}
finish_test
-3
View File
@@ -109,9 +109,6 @@ do_execsql_test hexlit-301 {
do_catchsql_test hexlist-400 {
SELECT 0x10000000000000000;
} {1 {hex literal too big: 0x10000000000000000}}
do_catchsql_test hexlist-401 {
SELECT DISTINCT 0x10000000000000000;
} {1 {hex literal too big: 0x10000000000000000}}
do_catchsql_test hexlist-410 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x);
-11
View File
@@ -874,17 +874,6 @@ do_test sqllimits1-16.2 {
}
} {1 {string or blob too big}}
do_catchsql_test sqllimits1.17.0 {
SELECT *,*,*,*,*,*,*,* FROM (
SELECT *,*,*,*,*,*,*,* FROM (
SELECT *,*,*,*,*,*,*,* FROM (
SELECT *,*,*,*,*,*,*,* FROM (
SELECT *,*,*,*,*,*,*,* FROM (
SELECT 1,2,3,4,5,6,7,8,9,10
)
))))
} "1 {too many columns in result set}"
foreach {key value} [array get saved] {
catch {set $key $value}
+1 -1
View File
@@ -60,7 +60,7 @@ foreach s {
open close access getcwd stat fstat ftruncate
fcntl read pread write pwrite fchmod fallocate
pread64 pwrite64 unlink openDirectory mkdir rmdir
statvfs fchown geteuid umask mmap munmap mremap
statvfs fchown umask mmap munmap mremap
getpagesize readlink
} {
if {[test_syscall exists $s]} {lappend syscall_list $s}
+4 -4
View File
@@ -1306,10 +1306,10 @@ foreach {tn sql res filter} {
{xFilter {SELECT rowid, * FROM 't6' WHERE b >= ? AND b < ?} J K}
1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
{xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} J%}
{xFilter {SELECT rowid, * FROM 't6'}}
1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4}
{xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} j%}
{xFilter {SELECT rowid, * FROM 't6'}}
} {
set echo_module {}
do_execsql_test 18.$tn.1 $sql $res
@@ -1319,10 +1319,10 @@ foreach {tn sql res filter} {
do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON }
foreach {tn sql res filter} {
2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
{xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} J%}
{xFilter {SELECT rowid, * FROM 't6'}}
2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {}
{xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} j%}
{xFilter {SELECT rowid, * FROM 't6'}}
} {
set echo_module {}
do_execsql_test 18.$tn.1 $sql $res
-2
View File
@@ -46,5 +46,3 @@ do_test vtabE-1 {
ORDER BY t1.value, t2.value;
}
} {vtabE vtabE1 11 vtabE1 w x {} vtabE vtabE1 11 vtabE1 y z {} vtabE vtabE2 22 vtabE2 a b {} vtabE vtabE2 22 vtabE2 c d {}}
finish_test
-110
View File
@@ -1,110 +0,0 @@
# 2015 Nov 24
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. Specifically,
# it tests that the GLOB, LIKE and REGEXP operators are correctly exposed
# to virtual table implementations.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix vtabH
ifcapable !vtab {
finish_test
return
}
register_echo_module db
do_execsql_test 1.0 {
CREATE TABLE t6(a, b TEXT);
CREATE INDEX i6 ON t6(b, a);
CREATE VIRTUAL TABLE e6 USING echo(t6);
}
foreach {tn sql expect} {
1 "SELECT * FROM e6 WHERE b LIKE 'abc'" {
xBestIndex {SELECT rowid, * FROM 't6' WHERE b like ?}
xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} abc
}
2 "SELECT * FROM e6 WHERE b GLOB 'abc'" {
xBestIndex {SELECT rowid, * FROM 't6' WHERE b glob ?}
xFilter {SELECT rowid, * FROM 't6' WHERE b glob ?} abc
}
} {
do_test 1.$tn {
set echo_module {}
execsql $sql
set ::echo_module
} [list {*}$expect]
}
#--------------------------------------------------------------------------
register_tclvar_module db
set ::xyz 10
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE vars USING tclvar;
SELECT * FROM vars WHERE name = 'xyz';
} {xyz {} 10}
set x1 aback
set x2 abaft
set x3 abandon
set x4 abandonint
set x5 babble
set x6 baboon
set x7 backbone
set x8 backarrow
set x9 castle
db func glob gfunc
proc gfunc {a b} {
incr ::gfunc
return 1
}
db func like lfunc
proc lfunc {a b} {
incr ::gfunc 100
return 1
}
db func regexp rfunc
proc rfunc {a b} {
incr ::gfunc 10000
return 1
}
foreach ::tclvar_set_omit {0 1} {
foreach {tn expr res cnt} {
1 {value GLOB 'aban*'} {x3 abandon x4 abandonint} 2
2 {value LIKE '%ac%'} {x1 aback x7 backbone x8 backarrow} 300
3 {value REGEXP '^......$'} {x5 babble x6 baboon x9 castle} 30000
} {
if {$tn==3} breakpoint
db cache flush
set ::gfunc 0
if {$::tclvar_set_omit} {set cnt 0}
do_test 2.$tclvar_set_omit.$tn.1 {
execsql "SELECT name, value FROM vars WHERE name MATCH 'x*' AND $expr"
} $res
do_test 2.$tclvar_set_omit.$tn.2 {
set ::gfunc
} $cnt
}
}
finish_test