]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the sqlite3_overload_function() API - part of the virtual table
authordrh <drh@noemail.net>
Sat, 16 Sep 2006 21:45:14 +0000 (21:45 +0000)
committerdrh <drh@noemail.net>
Sat, 16 Sep 2006 21:45:14 +0000 (21:45 +0000)
interface. (CVS 3426)

FossilOrigin-Name: aa7728f9f5b80dbb1b3db124f84b9166bf72bdd3

ext/fts1/fts1.c
manifest
manifest.uuid
src/func.c
src/main.c
src/sqlite.h.in
src/sqliteInt.h
src/vdbeapi.c
test/fts1c.test
test/func.test
test/vtab1.test

index a36bae35bef678700239db3f324f8e83ec2ca0f2..389b12163ef12bfdc0374d6c47ab1ed7c4685d44 100644 (file)
@@ -908,11 +908,14 @@ typedef struct Query {
 typedef struct Snippet {
   int nMatch;     /* Total number of matches */
   int nAlloc;     /* Space allocated for aMatch[] */
-  struct {        /* One entry for each matching term */
-    int iCol;        /* The column that contains the match */
-    int iTerm;       /* The index in Query.pTerms[] of the matching term */
-    int iStart;      /* The offset to the first character of the term */
-    int nByte;       /* Number of bytes in the term */
+  struct snippetMatch { /* One entry for each matching term */
+    char exemplar;       /* True if this match should be shown in the snippet */
+    short int iCol;      /* The column that contains the match */
+    short int iTerm;     /* The index in Query.pTerms[] of the matching term */
+    short int nByte;     /* Number of bytes in the term */
+    short int nContext;  /* Number of bytes of context for this match */
+    int iStart;          /* The offset to the first character of the term */
+    int iContext;        /* Start of the context */
   } *aMatch;      /* Points to space obtained from malloc */
   char *zOffset;  /* Text rendering of aMatch[] */
   int nOffset;    /* strlen(zOffset) */
@@ -2011,6 +2014,7 @@ static void snippetAppendMatch(
   int iStart, int nByte     /* Offset and size of the match */
 ){
   int i;
+  struct snippetMatch *pMatch;
   if( p->nMatch+1>=p->nAlloc ){
     p->nAlloc = p->nAlloc*2 + 10;
     p->aMatch = realloc(p->aMatch, p->nAlloc*sizeof(p->aMatch[0]) );
@@ -2021,10 +2025,12 @@ static void snippetAppendMatch(
     }
   }
   i = p->nMatch++;
-  p->aMatch[i].iCol = iCol;
-  p->aMatch[i].iTerm = iTerm;
-  p->aMatch[i].iStart = iStart;
-  p->aMatch[i].nByte = nByte;
+  pMatch = &p->aMatch[i];
+  pMatch->exemplar = 0;
+  pMatch->iCol = iCol;
+  pMatch->iTerm = iTerm;
+  pMatch->iStart = iStart;
+  pMatch->nByte = nByte;
 }
 
 /*
@@ -2143,20 +2149,49 @@ static void snippetAllOffsets(fulltext_cursor *p){
 */
 static void snippetOffsetText(Snippet *p){
   int i;
+  int cnt = 0;
   StringBuffer sb;
   char zBuf[200];
   if( p->zOffset ) return;
   initStringBuffer(&sb);
   for(i=0; i<p->nMatch; i++){
+    struct snippetMatch *pMatch = &p->aMatch[i];
     zBuf[0] = ' ';
-    sprintf(&zBuf[i>0], "%d %d %d %d", p->aMatch[i].iCol,
-        p->aMatch[i].iTerm, p->aMatch[i].iStart, p->aMatch[i].nByte);
+    sprintf(&zBuf[cnt>0], "%d %d %d %d", pMatch->iCol,
+        pMatch->iTerm, pMatch->iStart, pMatch->nByte);
     append(&sb, zBuf);
+    cnt++;
   }
   p->zOffset = sb.s;
   p->nOffset = sb.len;
 }
 
+/*
+** Scan all matches in Snippet and mark the exemplars.  Exemplars are
+** matches that we definitely want to include in the snippet.
+**
+** Generally speaking, each keyword in the search phrase will have
+** a single exemplar.  When a keyword matches at multiple points
+** within the document, the trick is figuring which of these matches
+** should be the examplar.
+*/
+static void snippetFindExemplars(Snippet *p, Query *pQ){
+  int i, j;
+  for(i=0; i<pQ->nTerms; i++){
+    for(j=0; j<p->nMatch; j++){
+      if( p->aMatch[j].iTerm==i ){
+        p->aMatch[j].exemplar = 1;
+        break;
+      }
+    }
+  }
+}
+
+static void snippetText(Snippet *p, Query *pQ){
+  
+}
+
+
 /*
 ** Close the cursor.  For additional information see the documentation
 ** on the xClose method of the virtual table interface.
index 0f884772a770ccc4b30610f1308afa689f4fd060..9263f99918ffc3ab32332060f65b6c101d3e8ea9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sdocumentation\sfor\sthe\ssqlite3_extended_result_codes()\sAPI.\s(CVS\s3425)
-D 2006-09-15T16:58:49
+C Add\sthe\ssqlite3_overload_function()\sAPI\s-\spart\sof\sthe\svirtual\stable\ninterface.\s(CVS\s3426)
+D 2006-09-16T21:45:14
 F Makefile.in cabd42d34340f49260bc2a7668c38eba8d4cfd99
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -21,7 +21,7 @@ F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
 F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
 F ext/fts1/ft_hash.h 1a35e654a235c2c662d3ca0dfc3138ad60b8b7d5
-F ext/fts1/fts1.c ff2b92dd289123bcbd9959207341b4e77fc42317
+F ext/fts1/fts1.c 10d0c351fb1ee51ef3b8bd3eb29d1f7f91773ddb
 F ext/fts1/fts1.h 6060b8f62c1d925ea8356cb1a6598073eb9159a6
 F ext/fts1/fts1_hash.c 3196cee866edbebb1c0521e21672e6d599965114
 F ext/fts1/fts1_hash.h 957d378355ed29f672cd5add012ce8b088a5e089
@@ -57,13 +57,13 @@ F src/date.c d5519023569adf30892ff7be6deadf25ecdf1ecd
 F src/delete.c 804384761144fe1a5035b99f4bd7d706976831bd
 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
 F src/expr.c 0546cc60f08c426d96092dea0789d085aed3580e
-F src/func.c dd9cea8ed3246d7a4c49fd01034d470d5702b8b0
+F src/func.c af537156dfeb91dbac8ffed4db6c4fa1a3164cc9
 F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185
 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
 F src/insert.c e9526ced19978a55687b55faea969b6ff2a53fb4
 F src/legacy.c 2631df6a861f830d6b1c0fe92b9fdd745b2c0cd6
 F src/loadext.c 5ffbf47d9ed168507e38ab7d09b1827ea3c9ca6d
-F src/main.c e284169854d429cc6550a22b8b136ca70164ce5b
+F src/main.c b9cf8dd198b0463b3de8954744e7cac6a1218126
 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
 F src/os.c 59f05de8c5777c34876607114a2fbe55ae578235
 F src/os.h 3fd6a022bafd620fdfd779a51dccb42f31c97f75
@@ -86,9 +86,9 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
 F src/select.c 0d4724930a1f34c747105ed1802fa4af0d8eb519
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 672326e8d90394218509f1820ab0835e7ed2bc06
-F src/sqlite.h.in 0d1b16b059bfcd286779ef40dd567f1e642f0df5
+F src/sqlite.h.in bf935004029631fd93d119bcf2f7259b9cb9ad5e
 F src/sqlite3ext.h 11a046b3519c4b9b7709e6d6a95c3a36366f684a
-F src/sqliteInt.h 74b39f55f30c3cff8935eb7adbd8842bca68331e
+F src/sqliteInt.h c1d28fb13003c03fe7787d7ecc065d30530afc90
 F src/table.c 6d0da66dde26ee75614ed8f584a1996467088d06
 F src/tclsqlite.c e029f739bed90071789fe81a226d53e97a80a4d8
 F src/test1.c 47f1d62d90fbf131dc5bbcd1b1aa18791fa3bc79
@@ -115,7 +115,7 @@ F src/vacuum.c fb65647c362589ed4ebb342c85665cadbcbf980c
 F src/vdbe.c a77869949ddd0afe01443611edb949e24e67c91c
 F src/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa
 F src/vdbeInt.h e3eaab262b67b84474625cfc38aec1125c32834b
-F src/vdbeapi.c d5d3cb0701b66e541059a53c8a32d034bc86b7f7
+F src/vdbeapi.c f1858a5edc3a5e32d038514dd9e7e9091400a782
 F src/vdbeaux.c 7d15dcf0eab43b0f6b1bb840dc2a3126eb370f5b
 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
 F src/vdbemem.c 26623176bf1c616aa478da958fac49502491a921
@@ -192,8 +192,8 @@ F test/fkey1.test 153004438d51e6769fb1ce165f6313972d6263ce
 F test/format4.test bf3bed3b13c63abfb3cfec232597a319a31d0bcc
 F test/fts1a.test 54fd9451c00fb91074d5abdc207b05dcba6d2d65
 F test/fts1b.test 5742c32c69ec9667c8d32df5bc79aa416d5f363a
-F test/fts1c.test 324895adf9855751f0ea7a6b735f8b7fcf28c3f8
-F test/func.test 7f2c91a948a0a177635835dc9afa078413c54ae1
+F test/fts1c.test 65a4e5a900ca0e0c9cd05612f9baf958d67a9d44
+F test/func.test 0ed54b5aeaad319f68016c033acfebef56f5874a
 F test/hook.test 7e7645fd9a033f79cce8fdff151e32715e7ec50a
 F test/in.test 369cb2aa1eab02296b4ec470732fe8c131260b1d
 F test/index.test e65df12bed94b2903ee89987115e1578687e9266
@@ -315,7 +315,7 @@ F test/vacuum.test 37f998b841cb335397c26d9bbc3457182af2565f
 F test/vacuum2.test 5aea8c88a65cb29f7d175296e7c819c6158d838c
 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
 F test/view.test 852bd4101e6d171c46ad682eb5c5faf662b2eba4
-F test/vtab1.test c7275c6c6575dfbbd975757f646f94477a6ea5c0
+F test/vtab1.test 30f82f7c3ee7ff9c0bba293d83b249488349c371
 F test/vtab2.test 43763026b124e68785de05d3fbf957a4b5f81a0d
 F test/vtab3.test f38d6d7d19f08bffdadce4d5b8cba078f8118587
 F test/vtab4.test a9d7104d41a787754a734740d7aa61c807a69f87
@@ -399,7 +399,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 5a18dd88498ca35ca1333d88c4635868d0b61073
-R db2e22fec0c46956a77b6266569df6f6
+P a6b3f6bed209dc27d36cd4e159159f73266e9911
+R 41c034b9dce9d7c6fde9c3e87e61b1e4
 U drh
-Z b17dc9813a2e708d175a29c8b1fb19be
+Z 9301301f42636d8c9fe0c165b69e993c
index e6133445b8c1a5a51f88b3f799c27ceab79ebf78..4b286c870d6ff33ab76ab8f8d2a292cb17fee9ec 100644 (file)
@@ -1 +1 @@
-a6b3f6bed209dc27d36cd4e159159f73266e9911
\ No newline at end of file
+aa7728f9f5b80dbb1b3db124f84b9166bf72bdd3
\ No newline at end of file
index 179d5d36635eba85928de51e79bc70d4b52bdb64..11a6e1ad13b05bca3c4eeef38fa31bf3cb1cedb7 100644 (file)
@@ -16,7 +16,7 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: func.c,v 1.133 2006/08/19 11:34:01 drh Exp $
+** $Id: func.c,v 1.134 2006/09/16 21:45:14 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -548,19 +548,6 @@ static void versionFunc(
   sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC);
 }
 
-/*
-** The MATCH() function is unimplemented.  If anybody tries to use it,
-** return an error.
-*/
-static void matchStub(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  static const char zErr[] = "MATCH is not implemented";
-  sqlite3_result_error(context, zErr, sizeof(zErr)-1);
-}
-
 
 /*
 ** EXPERIMENTAL - This is not an official function.  The interface may
@@ -1043,7 +1030,6 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
     { "last_insert_rowid",  0, 1, SQLITE_UTF8,    0, last_insert_rowid },
     { "changes",            0, 1, SQLITE_UTF8,    0, changes    },
     { "total_changes",      0, 1, SQLITE_UTF8,    0, total_changes },
-    { "match",              2, 0, SQLITE_UTF8,    0, matchStub },
 #ifdef SQLITE_SOUNDEX
     { "soundex",            1, 0, SQLITE_UTF8, 0, soundexFunc},
 #endif
@@ -1116,6 +1102,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
     }
   }
   sqlite3RegisterDateTimeFunctions(db);
+  sqlite3_overload_function(db, "MATCH", 2);
 #ifdef SQLITE_SSE
   (void)sqlite3SseFunctions(db);
 #endif
index 476577f118a54843f15b15a462c1dfedf4f85284..8b2663d0b46fcef41d1be8d7d0f4c4b4245e33da 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.357 2006/09/15 07:28:50 drh Exp $
+** $Id: main.c,v 1.358 2006/09/16 21:45:14 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -541,6 +541,32 @@ int sqlite3_create_function16(
 }
 #endif
 
+
+/*
+** Declare that a function has been overloaded by a virtual table.
+**
+** If the function already exists as a regular global function, then
+** this routine is a no-op.  If the function does not exist, then create
+** a new one that always throws a run-time error.  
+**
+** When virtual tables intend to provide an overloaded function, they
+** should call this routine to make sure the global function exists.
+** A global function must exist in order for name resolution to work
+** properly.
+*/
+int sqlite3_overload_function(
+  sqlite3 *db,
+  const char *zName,
+  int nArg
+){
+  int nName = strlen(zName);
+  if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
+    sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
+                      0, sqlite3InvalidFunction, 0, 0);
+  }
+  return sqlite3ApiExit(db, SQLITE_OK);
+}
+
 #ifndef SQLITE_OMIT_TRACE
 /*
 ** Register a trace function.  The pArg from the previously registered trace
@@ -908,8 +934,8 @@ static int openDatabase(
   ** is accessed.
   */
   if( !sqlite3MallocFailed() ){
-    sqlite3RegisterBuiltinFunctions(db);
     sqlite3Error(db, SQLITE_OK, 0);
+    sqlite3RegisterBuiltinFunctions(db);
   }
   db->magic = SQLITE_MAGIC_OPEN;
 
index 3028148840c69e58f5756c477d7062659e095ba8..f54bf816b7d71afbf57b084d8e81e9ca8b16f052 100644 (file)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.193 2006/09/15 07:28:50 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.194 2006/09/16 21:45:14 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -1782,6 +1782,24 @@ struct sqlite3_vtab_cursor {
 */
 int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable);
 
+/*
+** Virtual tables can provide alternative implementations of functions
+** using the xFindFunction method.  But global versions of those functions
+** must exist in order to be overloaded.
+**
+** This API makes sure a global version of a function with a particular
+** name and number of parameters exists.  If no such function exists
+** before this API is called, a new function is created.  The implementation
+** of the new function always causes an exception to be thrown.  So
+** the new function is not good for anything by itself.  Its only
+** purpose is to be a place-holder function that can be overloaded
+** by virtual tables.
+**
+** This API should be considered part of the virtual table interface,
+** which is experimental and subject to change.
+*/
+int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+
 /*
 ** The interface to the virtual-table mechanism defined above (back up
 ** to a comment remarkably similar to this one) is currently considered
index 3aa94ff34af5251c20895d52757d7ecec04c132a..4f2cc4b87318b540dce01a5dd812b7e64a5cf8eb 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.527 2006/09/15 07:28:50 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.528 2006/09/16 21:45:14 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1874,6 +1874,7 @@ int sqlite3VtabCallConnect(Parse*, Table*);
 int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
 int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *);
 FuncDef *sqlite3VtabOverloadFunction(FuncDef*, int nArg, Expr*);
+void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
 
 #ifdef SQLITE_SSE
 #include "sseInt.h"
index 983f164cbd06427b4c485f495b39bb070425a0fe..4758e967305b43b6cc3e81649aed324bf037becb 100644 (file)
@@ -267,6 +267,27 @@ void *sqlite3_user_data(sqlite3_context *p){
   return p->pFunc->pUserData;
 }
 
+/*
+** The following is the implementation of an SQL function that always
+** fails with an error message stating that the function is used in the
+** wrong context.  The sqlite3_overload_function() API might construct
+** SQL function that use this routine so that the functions will exist
+** for name resolution but are actually overloaded by the xFindFunction
+** method of virtual tables.
+*/
+void sqlite3InvalidFunction(
+  sqlite3_context *context,  /* The function calling context */
+  int argc,                  /* Number of arguments to the function */
+  sqlite3_value **argv       /* Value of each argument */
+){
+  const char *zName = context->pFunc->zName;
+  char *zErr;
+  zErr = sqlite3MPrintf(
+      "unable to use function %s in the requested context", zName);
+  sqlite3_result_error(context, zErr, -1);
+  sqliteFree(zErr);
+}
+
 /*
 ** Allocate or return the aggregate context for a user function.  A new
 ** context is allocated on the first call.  Subsequent calls return the
index 76bd854974be98a886a192c2030d83ff74b5e12c..db0f19e0f6d402d1bed4ef5f2e601d99c23bb3ce 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is testing the FTS1 module.
 #
-# $Id: fts1c.test,v 1.4 2006/09/15 07:28:51 drh Exp $
+# $Id: fts1c.test,v 1.5 2006/09/16 21:45:14 drh Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -351,9 +351,9 @@ Dick Jenkins:     East Marketeast
 WK 
 ');
 INSERT INTO email([from],[to],subject,body) VALUES('david.forster@enron.com', 'eol.wide@enron.com', 'Change to Stack Manager', 'Effective immediately, there is a change to the Stack Manager which will 
-affect Inactive Children.
+affect any Inactive Child.
 
-Inactive Children with links to Parent products will not have their 
+An inactive Child with links to Parent products will not have their 
 calculated prices updated until the Child product is Activated.
 
 When the Child Product is activated, the price will be recalculated and 
@@ -1066,5 +1066,56 @@ do_test fts1c-1.9 {
   }
 } {6 17 24 25 38 40 42 73 74}
 
+# Some simple tests of the automatic "offset" column.  In the sample
+# data set above, only one message, number 20, contains the words
+# "gas" and "reminder" in both body and subject.
+#
+do_test fts1c-2.1 {
+  execsql {
+    SELECT rowid, offset FROM email
+     WHERE _all MATCH 'gas reminder'
+  }
+} {20 {2 0 42 3 2 1 54 8 3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}}
+do_test fts1c-2.2 {
+  execsql {
+    SELECT rowid, offset FROM email
+     WHERE _all MATCH 'subject:gas reminder'
+  }
+} {20 {2 0 42 3 2 1 54 8 3 1 54 8}}
+do_test fts1c-2.3 {
+  execsql {
+    SELECT rowid, offset FROM email
+     WHERE _all MATCH 'body:gas reminder'
+  }
+} {20 {2 1 54 8 3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}}
+do_test fts1c-2.4 {
+  execsql {
+    SELECT rowid, offset FROM email
+     WHERE subject MATCH 'gas reminder'
+  }
+} {20 {2 0 42 3 2 1 54 8}}
+do_test fts1c-2.5 {
+  execsql {
+    SELECT rowid, offset FROM email
+     WHERE body MATCH 'gas reminder'
+  }
+} {20 {3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}}
+
+# Document 32 contains 5 instances of the world "child".  But only
+# 3 of them are paired with "product".  Make sure only those instances
+# that match the phrase appear in the offset list.
+#
+do_test fts1c-3.1 {
+  execsql {
+    SELECT rowid, offset FROM email
+     WHERE body MATCH 'child product' AND +rowid=32
+  }
+} {32 {3 0 94 5 3 0 114 5 3 0 207 5 3 1 213 7 3 0 245 5 3 1 251 7 3 0 409 5 3 1 415 7 3 1 493 7}}
+do_test fts1c-3.2 {
+  execsql {
+    SELECT rowid, offset FROM email
+     WHERE body MATCH '"child product"'
+  }
+} {32 {3 0 207 5 3 1 213 7 3 0 245 5 3 1 251 7 3 0 409 5 3 1 415 7}}
 
 finish_test
index d6d609a28008b2695a81ac7cb4cf3e2ce1c4b6c3..4eca470b7df9fb7d54b9a1a5e5310caddbd609d0 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing built-in functions.
 #
-# $Id: func.test,v 1.54 2006/08/19 11:34:02 drh Exp $
+# $Id: func.test,v 1.55 2006/09/16 21:45:14 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -659,12 +659,12 @@ do_test func-19.2 {
   catchsql {
     SELECT 'abc' MATCH 'xyz';
   }
-} {1 {MATCH is not implemented}}
+} {1 {unable to use function MATCH in the requested context}}
 do_test func-19.3 {
   catchsql {
     SELECT 'abc' NOT MATCH 'xyz';
   }
-} {1 {MATCH is not implemented}}
+} {1 {unable to use function MATCH in the requested context}}
 do_test func-19.4 {
   catchsql {
     SELECT match(1,2,3);
index 7804587abf8cb3f644fe01b7d1aea5f3a2c7c565..0ad04442c95f0917353cf4c90b26db9177b03188 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is creating and dropping virtual tables.
 #
-# $Id: vtab1.test,v 1.37 2006/09/02 22:14:59 drh Exp $
+# $Id: vtab1.test,v 1.38 2006/09/16 21:45:14 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -389,7 +389,7 @@ do_test vtab1-3.12 {
   catchsql {
     SELECT * FROM t1 WHERE a MATCH 'string';
   }
-} {1 {MATCH is not implemented}}
+} {1 {unable to use function MATCH in the requested context}}
 do_test vtab1-3.13 {
   set echo_module
 } [list xBestIndex {SELECT rowid, * FROM 'treal'} \