Improve test coverage of fts5.c.

FossilOrigin-Name: add4f4681c648dcbecaa68d08f7b2f4e6d63003c
This commit is contained in:
dan
2015-05-01 12:14:23 +00:00
parent 7b2ec1ae41
commit 557085a5a1
6 changed files with 223 additions and 27 deletions
+9 -3
View File
@@ -1495,6 +1495,9 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
return rc;
}
/*
** Implementation of the xSetAuxdata() method.
*/
static int fts5ApiSetAuxdata(
Fts5Context *pCtx, /* Fts5 context */
void *pPtr, /* Pointer to save as auxdata */
@@ -1503,6 +1506,8 @@ static int fts5ApiSetAuxdata(
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5Auxdata *pData;
/* Search through the cursors list of Fts5Auxdata objects for one that
** corresponds to the currently executing auxiliary function. */
for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
if( pData->pAux==pCsr->pAux ) break;
}
@@ -1512,12 +1517,12 @@ static int fts5ApiSetAuxdata(
pData->xDelete(pData->pPtr);
}
}else{
pData = (Fts5Auxdata*)sqlite3_malloc(sizeof(Fts5Auxdata));
int rc = SQLITE_OK;
pData = (Fts5Auxdata*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Auxdata));
if( pData==0 ){
if( xDelete ) xDelete(pPtr);
return SQLITE_NOMEM;
return rc;
}
memset(pData, 0, sizeof(Fts5Auxdata));
pData->pAux = pCsr->pAux;
pData->pNext = pCsr->pAuxdata;
pCsr->pAuxdata = pData;
@@ -1644,6 +1649,7 @@ static void fts5ApiCallback(
if( pCsr==0 ){
char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
sqlite3_result_error(context, zErr, -1);
sqlite3_free(zErr);
}else{
fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
}
+60 -14
View File
@@ -61,6 +61,27 @@ static int f5tDbPointer(Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **ppDb){
/* End of code that accesses the SqliteDb struct.
**************************************************************************/
static int f5tResultToErrorCode(const char *zRes){
struct ErrorCode {
int rc;
const char *zError;
} aErr[] = {
{ SQLITE_DONE, "SQLITE_DONE" },
{ SQLITE_ERROR, "SQLITE_ERROR" },
{ SQLITE_OK, "SQLITE_OK" },
{ SQLITE_OK, "" },
};
int i;
for(i=0; i<sizeof(aErr)/sizeof(aErr[0]); i++){
if( 0==sqlite3_stricmp(zRes, aErr[i].zError) ){
return aErr[i].rc;
}
}
return SQLITE_ERROR;
}
static int f5tDbAndApi(
Tcl_Interp *interp,
Tcl_Obj *pObj,
@@ -170,6 +191,10 @@ static int xQueryPhraseCb(
Tcl_DecrRefCount(pEval);
Tcl_DeleteCommand(p->interp, zCmd);
if( rc==TCL_OK ){
rc = f5tResultToErrorCode(Tcl_GetStringResult(p->interp));
}
return rc;
}
@@ -195,20 +220,22 @@ static int xF5tApi(
int nArg;
const char *zMsg;
} aSub[] = {
{ "xColumnCount", 0, "" },
{ "xRowCount", 0, "" },
{ "xColumnTotalSize", 1, "COL" },
{ "xTokenize", 2, "TEXT SCRIPT" },
{ "xPhraseCount", 0, "" },
{ "xPhraseSize", 1, "PHRASE" },
{ "xInstCount", 0, "" },
{ "xInst", 1, "IDX" },
{ "xRowid", 0, "" },
{ "xColumnText", 1, "COL" },
{ "xColumnSize", 1, "COL" },
{ "xQueryPhrase", 2, "PHRASE SCRIPT" },
{ "xSetAuxdata", 1, "VALUE" },
{ "xGetAuxdata", 1, "CLEAR" },
{ "xColumnCount", 0, "" }, /* 0 */
{ "xRowCount", 0, "" }, /* 1 */
{ "xColumnTotalSize", 1, "COL" }, /* 2 */
{ "xTokenize", 2, "TEXT SCRIPT" }, /* 3 */
{ "xPhraseCount", 0, "" }, /* 4 */
{ "xPhraseSize", 1, "PHRASE" }, /* 5 */
{ "xInstCount", 0, "" }, /* 6 */
{ "xInst", 1, "IDX" }, /* 7 */
{ "xRowid", 0, "" }, /* 8 */
{ "xColumnText", 1, "COL" }, /* 9 */
{ "xColumnSize", 1, "COL" }, /* 10 */
{ "xQueryPhrase", 2, "PHRASE SCRIPT" }, /* 11 */
{ "xSetAuxdata", 1, "VALUE" }, /* 12 */
{ "xGetAuxdata", 1, "CLEAR" }, /* 13 */
{ "xSetAuxdataInt", 1, "INTEGER" }, /* 14 */
{ "xGetAuxdataInt", 1, "CLEAR" }, /* 15 */
{ 0, 0, 0}
};
@@ -386,6 +413,25 @@ static int xF5tApi(
break;
}
/* These two - xSetAuxdataInt and xGetAuxdataInt - are similar to the
** xSetAuxdata and xGetAuxdata methods implemented above. The difference
** is that they may only save an integer value as auxiliary data, and
** do not specify a destructor function. */
CASE(14, "xSetAuxdataInt") {
int iVal;
if( Tcl_GetIntFromObj(interp, objv[2], &iVal) ) return TCL_ERROR;
rc = p->pApi->xSetAuxdata(p->pFts, (void*)iVal, 0);
break;
}
CASE(15, "xGetAuxdataInt") {
int iVal;
int bClear;
if( Tcl_GetBooleanFromObj(interp, objv[2], &bClear) ) return TCL_ERROR;
iVal = (int)p->pApi->xGetAuxdata(p->pFts, bClear);
Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal));
break;
}
default:
assert( 0 );
break;
+128
View File
@@ -52,6 +52,134 @@ do_execsql_test 2.2 {
} {2 3}
#-------------------------------------------------------------------------
# Test the xSet and xGetAuxdata APIs with a NULL destructor.
#
proc prevrowid {add cmd} {
set res [$cmd xGetAuxdataInt 0]
set r [$cmd xRowid]
$cmd xSetAuxdataInt $r
return [expr $res + $add]
}
sqlite3_fts5_create_function db prevrowid [list prevrowid 0]
sqlite3_fts5_create_function db prevrowid1 [list prevrowid 1]
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE e5 USING fts5(x);
INSERT INTO e5 VALUES('a b c');
INSERT INTO e5 VALUES('d e f');
INSERT INTO e5 VALUES('a b c');
INSERT INTO e5 VALUES('d e f');
INSERT INTO e5 VALUES('a b c');
}
do_execsql_test 3.1 {
SELECT prevrowid(e5) || '+' || rowid FROM e5 WHERE e5 MATCH 'c'
} {0+1 1+3 3+5}
do_execsql_test 3.2 {
SELECT prevrowid(e5) || '+' || prevrowid1(e5) || '+' || rowid
FROM e5 WHERE e5 MATCH 'e'
} {0+1+2 2+3+4}
#-------------------------------------------------------------------------
# Test that if the xQueryPhrase callback returns other than SQLITE_OK,
# the query is abandoned. And that if it returns an error code other than
# SQLITE_DONE, the error is propagated back to the caller.
#
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE e7 USING fts5(x);
INSERT INTO e7 VALUES('a x a');
INSERT INTO e7 VALUES('b x b');
INSERT INTO e7 VALUES('c x c');
INSERT INTO e7 VALUES('d x d');
INSERT INTO e7 VALUES('e x e');
}
proc xCallback {rowid code cmd} {
set r [$cmd xRowid]
lappend ::cb $r
if {$r==$rowid} { return $code }
return ""
}
proc phrasequery {cmd code} {
set ::cb [list]
$cmd xQueryPhrase 1 [list xCallback [$cmd xRowid] $code]
set ::cb
}
sqlite3_fts5_create_function db phrasequery phrasequery
do_execsql_test 4.1 {
SELECT phrasequery(e7, 'SQLITE_OK') FROM e7 WHERE e7 MATCH 'c x'
} {{1 2 3 4 5}}
do_execsql_test 4.2 {
SELECT phrasequery(e7, 'SQLITE_DONE') FROM e7 WHERE e7 MATCH 'c x'
} {{1 2 3}}
do_catchsql_test 4.3 {
SELECT phrasequery(e7, 'SQLITE_ERROR') FROM e7 WHERE e7 MATCH 'c x'
} {1 SQLITE_ERROR}
#-------------------------------------------------------------------------
# Auxiliary function calls with many cursors in the global cursor list.
#
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE e9 USING fts5(y);
INSERT INTO e9(rowid, y) VALUES(1, 'i iii');
INSERT INTO e9(rowid, y) VALUES(2, 'ii iv');
INSERT INTO e9(rowid, y) VALUES(3, 'ii');
INSERT INTO e9(rowid, y) VALUES(4, 'i iv');
INSERT INTO e9(rowid, y) VALUES(5, 'iii');
}
proc my_rowid {cmd} { $cmd xRowid }
sqlite3_fts5_create_function db my_rowid my_rowid
foreach {var q} {
s1 i
s2 ii
s3 iii
s4 iv
} {
set sql "SELECT my_rowid(e9) FROM e9 WHERE e9 MATCH '$q'"
set $var [sqlite3_prepare db $sql -1 dummy]
}
do_test 5.1.1 { sqlite3_step $s1 ; sqlite3_column_int $s1 0 } 1
do_test 5.1.2 { sqlite3_step $s2 ; sqlite3_column_int $s2 0 } 2
do_test 5.1.3 { sqlite3_step $s3 ; sqlite3_column_int $s3 0 } 1
do_test 5.1.4 { sqlite3_step $s4 ; sqlite3_column_int $s4 0 } 2
do_test 5.2.1 { sqlite3_step $s1 ; sqlite3_column_int $s1 0 } 4
do_test 5.2.2 { sqlite3_step $s2 ; sqlite3_column_int $s2 0 } 3
do_test 5.2.3 { sqlite3_step $s3 ; sqlite3_column_int $s3 0 } 5
do_test 5.2.4 { sqlite3_step $s4 ; sqlite3_column_int $s4 0 } 4
sqlite3_finalize $s1
sqlite3_finalize $s2
sqlite3_finalize $s3
sqlite3_finalize $s4
#-------------------------------------------------------------------------
# Passing an invalid first argument to an auxiliary function is detected.
#
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE e11 USING fts5(y, z);
INSERT INTO e11(rowid, y, z) VALUES(1, 'a b', 45);
INSERT INTO e11(rowid, y, z) VALUES(2, 'b c', 46);
}
do_catchsql_test 6.1 {
SELECT my_rowid(z) FROM e11 WHERE e11 MATCH 'b'
} {1 {no such cursor: 45}}
do_catchsql_test 6.2 {
SELECT my_rowid(y) FROM e11 WHERE e11 MATCH 'b'
} {1 {no such cursor: 0}}
finish_test
+16
View File
@@ -168,6 +168,8 @@ reset_db
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE x3 USING fts5(xxx);
INSERT INTO x3 VALUES('a b c d c b a');
INSERT INTO x3 VALUES('a a a a a a a');
INSERT INTO x3 VALUES('a a a a a a a');
}
do_faultsim_test 6.1 -faults oom-t* -body {
@@ -188,6 +190,20 @@ do_faultsim_test 6.2 -faults oom-t* -body {
faultsim_test_result {0 2} {1 SQLITE_NOMEM}
}
proc previc {cmd} {
set res [$cmd xGetAuxdataInt 0]
$cmd xSetAuxdataInt [$cmd xInstCount]
return $res
}
sqlite3_fts5_create_function db previc previc
do_faultsim_test 6.2 -faults oom-t* -body {
db eval { SELECT previc(x3) FROM x3 WHERE x3 MATCH 'a' }
} -test {
faultsim_test_result {0 {0 2 7}} {1 SQLITE_NOMEM}
}
+9 -9
View File
@@ -1,5 +1,5 @@
C Improve\sfts5\stests.
D 2015-04-29T20:54:08.849
C Improve\stest\scoverage\sof\sfts5.c.
D 2015-05-01T12:14:23.640
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 31b38b9da2e4b36f54a013bd71a5c3f6e45ca78f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -104,7 +104,7 @@ F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl 159c1194da0bc72f51b3c2eb71022568006dc5ad
F ext/fts5/extract_api_docs.tcl 55a6d648d516f35d9a1e580ac00de27154e1904a
F ext/fts5/fts5.c 932284a253cc9bb32caf047879669720680be2c3
F ext/fts5/fts5.c 3a0a73bcfbcb7e65ccda099cfb8fd268d2480c7e
F ext/fts5/fts5.h 24a2cc35b5e76eec57b37ba48c12d9d2cb522b3a
F ext/fts5/fts5Int.h 2e0a1a6b77e1e014b7e9b1479ca686ff79930457
F ext/fts5/fts5_aux.c d53f00f31ad615ca4f139dd8751f9041afa00971
@@ -114,7 +114,7 @@ F ext/fts5/fts5_expr.c 663c75dfdb1bfd8809d696357d7b55f507815098
F ext/fts5/fts5_hash.c 29d8b0668727863cc1f1efa65efe4dd78635b016
F ext/fts5/fts5_index.c de588982b0237b1605d6c37afd115b34c95c3da1
F ext/fts5/fts5_storage.c ef60fc9dcc4e274f9589165e26833173c273ae18
F ext/fts5/fts5_tcl.c 19ab8cfa642950648968dcf25075d6d969900524
F ext/fts5/fts5_tcl.c aa3b102bb01f366174718be7ce8e9311b9abb482
F ext/fts5/fts5_tokenize.c 830eae0d35a5a5a90af34df65da3427f46d942fc
F ext/fts5/fts5_unicode2.c f74f53316377068812a1fa5a37819e6b8124631d
F ext/fts5/fts5parse.y 777da8e5819f75c217982c79c29d014c293acac9
@@ -132,7 +132,7 @@ F ext/fts5/test/fts5ai.test f20e53bbf0c55bc596f1fd47f2740dae028b8f37
F ext/fts5/test/fts5aj.test 05b569f5c16ea3098fb1984eec5cf50dbdaae5d8
F ext/fts5/test/fts5ak.test 7b8c5df96df599293f920b7e5521ebc79f647592
F ext/fts5/test/fts5al.test e6bddd2c11c0d1e3ae189ee51081899d2f4ea570
F ext/fts5/test/fts5aux.test 1e475d928a3d1decf74167394db20330d7beeb0f
F ext/fts5/test/fts5aux.test d9c724351d8e4dc46cad1308c0b4b8ac94d07660
F ext/fts5/test/fts5auxdata.test c69b86092bf1a157172de5f9169731af3403179b
F ext/fts5/test/fts5bigpl.test b1cfd00561350ab04994ba7dd9d48468e5e0ec3b
F ext/fts5/test/fts5content.test 532e15b541254410adc7bfb51f94631cfe82de8f
@@ -145,7 +145,7 @@ F ext/fts5/test/fts5eb.test 728a1f23f263548f5c29b29dfb851b5f2dbe723e
F ext/fts5/test/fts5fault1.test ed71717a479bef32d05f02d9c48691011d160d4d
F ext/fts5/test/fts5fault2.test 26c3d70648f691e2cc9391e14bbc11a973656383
F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3
F ext/fts5/test/fts5fault4.test aea710bbf5680ed41afb9d3313c297d429f9feac
F ext/fts5/test/fts5fault4.test 087066bae36f41227eb85968a2436c8a9c960501
F ext/fts5/test/fts5full.test 0924bdca5416a242103239ace79c6f5aa34bab8d
F ext/fts5/test/fts5hash.test adb7b0442cc1c77c507f07e16d11490486e75dfa
F ext/fts5/test/fts5merge.test 453a0717881aa7784885217b2040f3f275caff03
@@ -1315,7 +1315,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 07f70955392697556ca2951c9b6c3a5204cd5ec0
R 07c0e8a626b67779b0890a98070e21c4
P c1f07a3aa98eac87e2747527d15e5e5562221ceb
R 67c24377157269f998af5007c163ea4c
U dan
Z 5236003ea42b936c8f2a3578dc6f6593
Z 082bd0388383a4ef8c727daa5b60df05
+1 -1
View File
@@ -1 +1 @@
c1f07a3aa98eac87e2747527d15e5e5562221ceb
add4f4681c648dcbecaa68d08f7b2f4e6d63003c