]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improve test coverage of fts5.c.
authordan <dan@noemail.net>
Fri, 1 May 2015 12:14:23 +0000 (12:14 +0000)
committerdan <dan@noemail.net>
Fri, 1 May 2015 12:14:23 +0000 (12:14 +0000)
FossilOrigin-Name: add4f4681c648dcbecaa68d08f7b2f4e6d63003c

ext/fts5/fts5.c
ext/fts5/fts5_tcl.c
ext/fts5/test/fts5aux.test
ext/fts5/test/fts5fault4.test
manifest
manifest.uuid

index b37f72d58dca2b6317d021bd27d0c6b322454498..a753d671da90c540102b15a4c02983f5345f89e8 100644 (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]);
   }
index 431533afcc9a9d8adc33d9874c6d7884b8efc7cd..171b4849a5ebfeffc22214f8bc46b82f358f2ab1 100644 (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;
index b5cbc6e9a310bdb8f0b6586a3fba78d17ba5aafa..61a28e50fb5e1c16d7fd209ac14f70dbc4625380 100644 (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
 
index d7ced10c720d93a254ebfca27e4dce57a32e2ea6..c0c9dd1d6c36f234dc1ce453a2e7cf06cccc448e 100644 (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}
+}
+
+
 
 
 
index 199e150b25b7a05f5df3c6f253f88db7b9cabbd9..5f785b7ee6eb71e21963dced672e1e9a3a06e2c2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index 615ae11606f008b1f6784853b757ec459672dee4..0a40e5a487b1808e2d09c9627ef40bb65cc37056 100644 (file)
@@ -1 +1 @@
-c1f07a3aa98eac87e2747527d15e5e5562221ceb
\ No newline at end of file
+add4f4681c648dcbecaa68d08f7b2f4e6d63003c
\ No newline at end of file