From: dan Date: Fri, 6 Oct 2017 18:00:36 +0000 (+0000) Subject: Add tests for the example fts3 "rank" function that appears in the X-Git-Tag: version-3.21.0~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a0ac086f15f7952b5e7865e0c5a9fa15bd208859;p=thirdparty%2Fsqlite.git Add tests for the example fts3 "rank" function that appears in the documentation. FossilOrigin-Name: 702b137aa4f76543647e177beeb1ca2b3cd18c61021c78880e9aa8656f341d65 --- diff --git a/manifest b/manifest index 78578c42d7..9ed6440a70 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompiler\swarnings\sthat\scome\sup\swith\sSQLITE_OMIT_WAL. -D 2017-10-05T20:57:38.304 +C Add\stests\sfor\sthe\sexample\sfts3\s"rank"\sfunction\sthat\sappears\sin\sthe\ndocumentation. +D 2017-10-06T18:00:36.541 F Makefile.in 4bc36d913c2e3e2d326d588d72f618ac9788b2fd4b7efda61102611a6495c3ff F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6033b51b6aea702ea059f6ab2d47b1d3cef648695f787247dd4fb395fe60673f @@ -489,7 +489,7 @@ F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 1960abbb234b97e9b920f07e99503fc04b443f62bbc3c6ff2c2cea2133e3b8a2 F src/test_fs.c 35a2f7dd8a915900873386331386d9ba1ae1b5026d74fd20c2807bc76221f291 -F src/test_func.c a4fdab3363b436c1b12660e9362ce3f3782b7b5e +F src/test_func.c 772bb74807d3485ce90c9347f5dfddec4a76ed9edd4cf6c58d2d79b9ce9064d6 F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64 @@ -864,6 +864,7 @@ F test/fts3offsets.test b85fd382abdc78ebce721d8117bd552dfb75094c F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2 F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce F test/fts3query.test f33eb71a1fe1084ea585eeb7ee76b390729f5170 +F test/fts3rank.test e4d2e16a28c98cae95001a75e2b4b05b19b051ffd6aaab15491c5e0595127b9b F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e F test/fts3snippet.test 01a4231816e03a0660ae53ba2404fe69012fe0db @@ -1655,7 +1656,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 373b0ace480aa303bbf512ea8806a17f6186b16d6316a7b724499bf94b3974d4 -R adacc5e670ad3c34f8576daa184cae71 -U drh -Z 9327d763f0b9382eb519713049c15b88 +P 8ca0fa8dfe6a66aea7fc63f15e6f704cb190aa0760a3fec2db5f6bad3861a135 +R 413648e1416f08d1828bb75a07c656dd +U dan +Z b857c7dffd71ebfaddd17b63d1fd16c3 diff --git a/manifest.uuid b/manifest.uuid index 9c51f15a9c..b8a9eb4154 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8ca0fa8dfe6a66aea7fc63f15e6f704cb190aa0760a3fec2db5f6bad3861a135 \ No newline at end of file +702b137aa4f76543647e177beeb1ca2b3cd18c61021c78880e9aa8656f341d65 \ No newline at end of file diff --git a/src/test_func.c b/src/test_func.c index c7860fe887..59fe677c33 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -791,6 +791,123 @@ abuse_err: } +/* +** SQLite user defined function to use with matchinfo() to calculate the +** relevancy of an FTS match. The value returned is the relevancy score +** (a real value greater than or equal to zero). A larger value indicates +** a more relevant document. +** +** The overall relevancy returned is the sum of the relevancies of each +** column value in the FTS table. The relevancy of a column value is the +** sum of the following for each reportable phrase in the FTS query: +** +** ( / ) * +** +** where is the number of instances of the phrase in the +** column value of the current row and is the number +** of instances of the phrase in the same column of all rows in the FTS +** table. The is a weighting factor assigned to each +** column by the caller (see below). +** +** The first argument to this function must be the return value of the FTS +** matchinfo() function. Following this must be one argument for each column +** of the FTS table containing a numeric weight factor for the corresponding +** column. Example: +** +** CREATE VIRTUAL TABLE documents USING fts3(title, content) +** +** The following query returns the docids of documents that match the full-text +** query sorted from most to least relevant. When calculating +** relevance, query term instances in the 'title' column are given twice the +** weighting of those in the 'content' column. +** +** SELECT docid FROM documents +** WHERE documents MATCH +** ORDER BY rank(matchinfo(documents), 1.0, 0.5) DESC +*/ +static void rankfunc(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ + int *aMatchinfo; /* Return value of matchinfo() */ + int nMatchinfo; /* Number of elements in aMatchinfo[] */ + int nCol = 0; /* Number of columns in the table */ + int nPhrase = 0; /* Number of phrases in the query */ + int iPhrase; /* Current phrase */ + double score = 0.0; /* Value to return */ + + assert( sizeof(int)==4 ); + + /* Check that the number of arguments passed to this function is correct. + ** If not, jump to wrong_number_args. Set aMatchinfo to point to the array + ** of unsigned integer values returned by FTS function matchinfo. Set + ** nPhrase to contain the number of reportable phrases in the users full-text + ** query, and nCol to the number of columns in the table. Then check that the + ** size of the matchinfo blob is as expected. Return an error if it is not. + */ + if( nVal<1 ) goto wrong_number_args; + aMatchinfo = (unsigned int *)sqlite3_value_blob(apVal[0]); + nMatchinfo = sqlite3_value_bytes(apVal[0]) / sizeof(int); + if( nMatchinfo>=2 ){ + nPhrase = aMatchinfo[0]; + nCol = aMatchinfo[1]; + } + if( nMatchinfo!=(2+3*nCol*nPhrase) ){ + sqlite3_result_error(pCtx, + "invalid matchinfo blob passed to function rank()", -1); + return; + } + if( nVal!=(1+nCol) ) goto wrong_number_args; + + /* Iterate through each phrase in the users query. */ + for(iPhrase=0; iPhrase / ) * + ** + ** aPhraseinfo[] points to the start of the data for phrase iPhrase. So + ** the hit count and global hit counts for each column are found in + ** aPhraseinfo[iCol*3] and aPhraseinfo[iCol*3+1], respectively. + */ + int *aPhraseinfo = &aMatchinfo[2 + iPhrase*nCol*3]; + for(iCol=0; iCol0 ){ + score += ((double)nHitCount / (double)nGlobalHitCount) * weight; + } + } + } + + sqlite3_result_double(pCtx, score); + return; + + /* Jump here if the wrong number of arguments are passed to this function */ +wrong_number_args: + sqlite3_result_error(pCtx, "wrong number of arguments to function rank()", -1); +} + +static int SQLITE_TCLAPI install_fts3_rank_function( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**); + sqlite3 *db; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + sqlite3_create_function(db, "rank", -1, SQLITE_UTF8, 0, rankfunc, 0, 0); + return TCL_OK; +} + + /* ** Register commands with the TCL interpreter. */ @@ -801,6 +918,7 @@ int Sqlitetest_func_Init(Tcl_Interp *interp){ } aObjCmd[] = { { "autoinstall_test_functions", autoinstall_test_funcs }, { "abuse_create_function", abuse_create_function }, + { "install_fts3_rank_function", install_fts3_rank_function }, }; int i; extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *); diff --git a/test/fts3rank.test b/test/fts3rank.test new file mode 100644 index 0000000000..7ee3143a76 --- /dev/null +++ b/test/fts3rank.test @@ -0,0 +1,64 @@ +# 2017 October 7 +# +# 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. The +# focus of this script is testing the FTS3 module. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix fts3expr5 + +# If SQLITE_ENABLE_FTS3 is defined, omit this file. +ifcapable !fts3 { + finish_test + return +} + +install_fts3_rank_function db +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts3(a, b); + INSERT INTO t1 VALUES('one two', 'one'); + INSERT INTO t1 VALUES('one two', 'three'); + INSERT INTO t1 VALUES('one two', 'two'); +} + +do_execsql_test 1.1 { + SELECT * FROM t1 WHERE t1 MATCH 'one' + ORDER BY rank(matchinfo(t1), 1.0, 1.0) DESC, rowid +} { + {one two} one + {one two} three + {one two} two +} + +do_execsql_test 1.2 { + SELECT * FROM t1 WHERE t1 MATCH 'two' + ORDER BY rank(matchinfo(t1), 1.0, 1.0) DESC, rowid +} { + {one two} two + {one two} one + {one two} three +} + +do_catchsql_test 1.3 { + SELECT * FROM t1 ORDER BY rank(matchinfo(t1), 1.0, 1.0) DESC, rowid +} {1 {invalid matchinfo blob passed to function rank()}} + +do_catchsql_test 1.4 { + SELECT * FROM t1 ORDER BY rank(x'0000000000000000') DESC, rowid +} {0 {{one two} one {one two} three {one two} two}} + +do_catchsql_test 1.5 { + SELECT * FROM t1 ORDER BY rank(x'0100000001000000') DESC, rowid +} {1 {invalid matchinfo blob passed to function rank()}} + +finish_test +