Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 426504965c |
@@ -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
@@ -1 +1 @@
|
||||
e70ec71d6883f2f8fc75301ff985bccb5aa06127
|
||||
093e0d10a81adc078dcb3e08e33ce89bdbe53789
|
||||
+1
-1
@@ -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
@@ -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 ){
|
||||
|
||||
@@ -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
@@ -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++){
|
||||
|
||||
@@ -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
@@ -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
|
||||
**
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
Reference in New Issue
Block a user