mirror of
https://github.com/sqlite/sqlite.git
synced 2025-05-31 11:21:21 +03:00
Add experimental support for LIKE, GLOB and REGEXP to the virtual table interface.
FossilOrigin-Name: 277a5b4027d4c2caba8143228a4f7d6df899dbb4
This commit is contained in:
parent
8836cbbcb4
commit
07bdba86d5
26
manifest
26
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fix\san\sobscure\smemory\sleak\sfound\sby\slibfuzzer\sthat\smay\soccur\sunder\ssome\scircumstances\sif\sexpanding\sa\s"*"\sexpression\scauses\sa\sSELECT\sto\sreturn\smore\sthan\s32767\scolumns.
|
C Add\sexperimental\ssupport\sfor\sLIKE,\sGLOB\sand\sREGEXP\sto\sthe\svirtual\stable\sinterface.
|
||||||
D 2015-11-21T19:43:29.760
|
D 2015-11-23T21:09:54.478
|
||||||
F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1
|
F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc e928e68168df69b353300ac87c10105206653a03
|
F Makefile.msc e928e68168df69b353300ac87c10105206653a03
|
||||||
@ -341,7 +341,7 @@ F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e
|
|||||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||||
F src/select.c e10586c750d87211caa8f4b239e2bfa6a2049e5b
|
F src/select.c e10586c750d87211caa8f4b239e2bfa6a2049e5b
|
||||||
F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c
|
F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c
|
||||||
F src/sqlite.h.in fa62718f73553f06b2f2e362fd09ccb4e1cbb626
|
F src/sqlite.h.in a71226fe80bded2af3b99c5aed7363ef486962e1
|
||||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||||
F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
|
F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
|
||||||
F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9
|
F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9
|
||||||
@ -356,7 +356,7 @@ F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
|||||||
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
|
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
|
||||||
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
|
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
|
||||||
F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3
|
F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3
|
||||||
F src/test8.c 610e3d523018ca63b08081795e76794a2121ec38
|
F src/test8.c 59d91e1ff19aa91603aa409d4f41568cab1b9a2d
|
||||||
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
||||||
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
|
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
|
||||||
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
|
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
|
||||||
@ -416,10 +416,10 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
|||||||
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
|
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
|
||||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||||
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
||||||
F src/where.c 6aceb72cc58dc06922a9e1604d559c8ca4c3e728
|
F src/where.c 6687fb2675d9c1c1936ceca77529e2f21fb3a769
|
||||||
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
|
F src/whereInt.h 6afc0d70cf6213e58e8fbe10b6e50d1aa16f122f
|
||||||
F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b
|
F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b
|
||||||
F src/whereexpr.c bd4877cd4dd11f6ab551ef0054535ca3c6224950
|
F src/whereexpr.c 12c6fa7576674d24bf0116364a39885925c89188
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
@ -1259,7 +1259,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
|||||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||||
F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9
|
F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9
|
||||||
F test/vtab1.test 6210e076997f176bedc300a87ad6404651b601dd
|
F test/vtab1.test ec5cb767277d7e0eff34d3a02824c1dd959a5959
|
||||||
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
|
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
|
||||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||||
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
|
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
|
||||||
@ -1274,6 +1274,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
|
|||||||
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
|
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
|
||||||
F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61
|
F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61
|
||||||
F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
|
F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
|
||||||
|
F test/vtabH.test 15e137d2af9b0b81fedca6697518eb8834c013f4
|
||||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||||
F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772
|
F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772
|
||||||
@ -1404,7 +1405,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 198d191b2f5ef7d63ac0093c701955c9052fd734
|
P 60de5f23424552c98aa760ac89149a3d51f895be
|
||||||
R 8ed8d9e954ea81e19ae35a6836359b00
|
R b6557d1407b51115ef511b97d0fc16c1
|
||||||
|
T *branch * vtab-like-operator
|
||||||
|
T *sym-vtab-like-operator *
|
||||||
|
T -sym-trunk *
|
||||||
U dan
|
U dan
|
||||||
Z f96d100152be981f85597b50bc9a8134
|
Z 249ced27266ff2c4ebd31fcaec9b55b5
|
||||||
|
@ -1 +1 @@
|
|||||||
60de5f23424552c98aa760ac89149a3d51f895be
|
277a5b4027d4c2caba8143228a4f7d6df899dbb4
|
@ -5709,12 +5709,15 @@ struct sqlite3_index_info {
|
|||||||
** an operator that is part of a constraint term in the wHERE clause of
|
** an operator that is part of a constraint term in the wHERE clause of
|
||||||
** a query that uses a [virtual table].
|
** a query that uses a [virtual table].
|
||||||
*/
|
*/
|
||||||
#define SQLITE_INDEX_CONSTRAINT_EQ 2
|
#define SQLITE_INDEX_CONSTRAINT_EQ 2
|
||||||
#define SQLITE_INDEX_CONSTRAINT_GT 4
|
#define SQLITE_INDEX_CONSTRAINT_GT 4
|
||||||
#define SQLITE_INDEX_CONSTRAINT_LE 8
|
#define SQLITE_INDEX_CONSTRAINT_LE 8
|
||||||
#define SQLITE_INDEX_CONSTRAINT_LT 16
|
#define SQLITE_INDEX_CONSTRAINT_LT 16
|
||||||
#define SQLITE_INDEX_CONSTRAINT_GE 32
|
#define SQLITE_INDEX_CONSTRAINT_GE 32
|
||||||
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
|
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
|
||||||
|
#define SQLITE_INDEX_CONSTRAINT_LIKE 65
|
||||||
|
#define SQLITE_INDEX_CONSTRAINT_GLOB 66
|
||||||
|
#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Register A Virtual Table Implementation
|
** CAPI3REF: Register A Virtual Table Implementation
|
||||||
|
@ -849,6 +849,12 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
|||||||
zOp = ">="; break;
|
zOp = ">="; break;
|
||||||
case SQLITE_INDEX_CONSTRAINT_MATCH:
|
case SQLITE_INDEX_CONSTRAINT_MATCH:
|
||||||
zOp = "LIKE"; break;
|
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' ){
|
if( zOp[0]=='L' ){
|
||||||
zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')",
|
zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')",
|
||||||
|
@ -893,6 +893,9 @@ static sqlite3_index_info *allocateIndexInfo(
|
|||||||
pIdxCons[j].iTermOffset = i;
|
pIdxCons[j].iTermOffset = i;
|
||||||
op = (u8)pTerm->eOperator & WO_ALL;
|
op = (u8)pTerm->eOperator & WO_ALL;
|
||||||
if( op==WO_IN ) op = WO_EQ;
|
if( op==WO_IN ) op = WO_EQ;
|
||||||
|
if( op==WO_MATCH ){
|
||||||
|
op = pTerm->eMatchOp;
|
||||||
|
}
|
||||||
pIdxCons[j].op = op;
|
pIdxCons[j].op = op;
|
||||||
/* The direct assignment in the previous line is possible only because
|
/* The direct assignment in the previous line is possible only because
|
||||||
** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
|
** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
|
||||||
|
@ -253,6 +253,7 @@ struct WhereTerm {
|
|||||||
u16 eOperator; /* A WO_xx value describing <op> */
|
u16 eOperator; /* A WO_xx value describing <op> */
|
||||||
u16 wtFlags; /* TERM_xxx bit flags. See below */
|
u16 wtFlags; /* TERM_xxx bit flags. See below */
|
||||||
u8 nChild; /* Number of children that must disable us */
|
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 */
|
WhereClause *pWC; /* The clause this term is part of */
|
||||||
Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
|
Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
|
||||||
Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
|
Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
|
||||||
|
@ -282,16 +282,24 @@ static int isLikeOrGlob(
|
|||||||
** If it is then return TRUE. If not, return FALSE.
|
** If it is then return TRUE. If not, return FALSE.
|
||||||
*/
|
*/
|
||||||
static int isMatchOfColumn(
|
static int isMatchOfColumn(
|
||||||
Expr *pExpr /* Test this expression */
|
Expr *pExpr, /* Test this expression */
|
||||||
|
unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */
|
||||||
){
|
){
|
||||||
|
struct Op2 {
|
||||||
|
const char *zOp;
|
||||||
|
unsigned char eOp2;
|
||||||
|
} aOp[] = {
|
||||||
|
{ "match", SQLITE_INDEX_CONSTRAINT_MATCH },
|
||||||
|
{ "glob", SQLITE_INDEX_CONSTRAINT_GLOB },
|
||||||
|
{ "like", SQLITE_INDEX_CONSTRAINT_LIKE },
|
||||||
|
{ "regex", SQLITE_INDEX_CONSTRAINT_REGEXP }
|
||||||
|
};
|
||||||
ExprList *pList;
|
ExprList *pList;
|
||||||
|
int i;
|
||||||
|
|
||||||
if( pExpr->op!=TK_FUNCTION ){
|
if( pExpr->op!=TK_FUNCTION ){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pList = pExpr->x.pList;
|
pList = pExpr->x.pList;
|
||||||
if( pList->nExpr!=2 ){
|
if( pList->nExpr!=2 ){
|
||||||
return 0;
|
return 0;
|
||||||
@ -299,7 +307,13 @@ static int isMatchOfColumn(
|
|||||||
if( pList->a[1].pExpr->op != TK_COLUMN ){
|
if( pList->a[1].pExpr->op != TK_COLUMN ){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
for(i=0; i<ArraySize(aOp); i++){
|
||||||
|
if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
|
||||||
|
*peOp2 = aOp[i].eOp2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
|
||||||
@ -876,6 +890,7 @@ static void exprAnalyze(
|
|||||||
int op; /* Top-level operator. pExpr->op */
|
int op; /* Top-level operator. pExpr->op */
|
||||||
Parse *pParse = pWInfo->pParse; /* Parsing context */
|
Parse *pParse = pWInfo->pParse; /* Parsing context */
|
||||||
sqlite3 *db = pParse->db; /* Database connection */
|
sqlite3 *db = pParse->db; /* Database connection */
|
||||||
|
unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */
|
||||||
|
|
||||||
if( db->mallocFailed ){
|
if( db->mallocFailed ){
|
||||||
return;
|
return;
|
||||||
@ -1099,7 +1114,7 @@ static void exprAnalyze(
|
|||||||
** virtual tables. The native query optimizer does not attempt
|
** virtual tables. The native query optimizer does not attempt
|
||||||
** to do anything with MATCH functions.
|
** to do anything with MATCH functions.
|
||||||
*/
|
*/
|
||||||
if( isMatchOfColumn(pExpr) ){
|
if( isMatchOfColumn(pExpr, &eOp2) ){
|
||||||
int idxNew;
|
int idxNew;
|
||||||
Expr *pRight, *pLeft;
|
Expr *pRight, *pLeft;
|
||||||
WhereTerm *pNewTerm;
|
WhereTerm *pNewTerm;
|
||||||
@ -1120,6 +1135,7 @@ static void exprAnalyze(
|
|||||||
pNewTerm->leftCursor = pLeft->iTable;
|
pNewTerm->leftCursor = pLeft->iTable;
|
||||||
pNewTerm->u.leftColumn = pLeft->iColumn;
|
pNewTerm->u.leftColumn = pLeft->iColumn;
|
||||||
pNewTerm->eOperator = WO_MATCH;
|
pNewTerm->eOperator = WO_MATCH;
|
||||||
|
pNewTerm->eMatchOp = eOp2;
|
||||||
markTermAsChild(pWC, idxNew, idxTerm);
|
markTermAsChild(pWC, idxNew, idxTerm);
|
||||||
pTerm = &pWC->a[idxTerm];
|
pTerm = &pWC->a[idxTerm];
|
||||||
pTerm->wtFlags |= TERM_COPIED;
|
pTerm->wtFlags |= TERM_COPIED;
|
||||||
|
@ -1306,10 +1306,10 @@ foreach {tn sql res filter} {
|
|||||||
{xFilter {SELECT rowid, * FROM 't6' WHERE b >= ? AND b < ?} J K}
|
{xFilter {SELECT rowid, * FROM 't6' WHERE b >= ? AND b < ?} J K}
|
||||||
|
|
||||||
1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
|
1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
|
||||||
{xFilter {SELECT rowid, * FROM 't6'}}
|
{xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} J%}
|
||||||
|
|
||||||
1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4}
|
1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4}
|
||||||
{xFilter {SELECT rowid, * FROM 't6'}}
|
{xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} j%}
|
||||||
} {
|
} {
|
||||||
set echo_module {}
|
set echo_module {}
|
||||||
do_execsql_test 18.$tn.1 $sql $res
|
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 }
|
do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON }
|
||||||
foreach {tn sql res filter} {
|
foreach {tn sql res filter} {
|
||||||
2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
|
2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
|
||||||
{xFilter {SELECT rowid, * FROM 't6'}}
|
{xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} J%}
|
||||||
|
|
||||||
2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {}
|
2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {}
|
||||||
{xFilter {SELECT rowid, * FROM 't6'}}
|
{xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} j%}
|
||||||
} {
|
} {
|
||||||
set echo_module {}
|
set echo_module {}
|
||||||
do_execsql_test 18.$tn.1 $sql $res
|
do_execsql_test 18.$tn.1 $sql $res
|
||||||
|
49
test/vtabH.test
Normal file
49
test/vtabH.test
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_test
|
Loading…
x
Reference in New Issue
Block a user