Add tests and minor fixes to the xFindFunction method of virtual tables. (CVS 3323)

FossilOrigin-Name: 3c4233e074cb016e2422b2e8f867c99217e9b10e
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index b5fce85..70cb8dd 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.186 2006/07/08 17:06:44 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.187 2006/07/08 18:09:15 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -1566,8 +1566,8 @@
   int (*xCommit)(sqlite3_vtab *pVTab);
   int (*xRollback)(sqlite3_vtab *pVTab);
   int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
-                       int (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
-                       void **ppArg, int *piPrefEnc);
+                       void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
+                       void **ppArg);
 };
 
 /*
diff --git a/src/test8.c b/src/test8.c
index bcacf98..3a639d9 100644
--- a/src/test8.c
+++ b/src/test8.c
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test8.c,v 1.39 2006/07/08 17:06:44 drh Exp $
+** $Id: test8.c,v 1.40 2006/07/08 18:09:15 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -897,6 +897,65 @@
 }
 
 /*
+** Implementation of "GLOB" function on the echo module.  Pass
+** all arguments to the ::echo_glob_overload procedure of TCL
+** and return the result of that procedure as a string.
+*/
+static void overloadedGlobFunction(
+  sqlite3_context *pContext,
+  int nArg,
+  sqlite3_value **apArg
+){
+  Tcl_Interp *interp = sqlite3_user_data(pContext);
+  Tcl_DString str;
+  int i;
+  int rc;
+  Tcl_DStringInit(&str);
+  Tcl_DStringAppendElement(&str, "::echo_glob_overload");
+  for(i=0; i<nArg; i++){
+    Tcl_DStringAppendElement(&str, (char*)sqlite3_value_text(apArg[i]));
+  }
+  rc = Tcl_Eval(interp, Tcl_DStringValue(&str));
+  Tcl_DStringFree(&str);
+  if( rc ){
+    sqlite3_result_error(pContext, Tcl_GetStringResult(interp), -1);
+  }else{
+    sqlite3_result_text(pContext, Tcl_GetStringResult(interp),
+                        -1, SQLITE_TRANSIENT);
+  }
+  Tcl_ResetResult(interp);
+}
+
+/*
+** This is the xFindFunction implementation for the echo module.
+** SQLite calls this routine when the first argument of a function
+** is a column of an echo virtual table.  This routine can optionally
+** override the implementation of that function.  It will choose to
+** do so if the function is named "glob", and a TCL command named
+** ::echo_glob_overload exists.
+*/
+static int echoFindFunction(
+  sqlite3_vtab *vtab,
+  int nArg,
+  const char *zFuncName,
+  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
+  void **ppArg
+){
+  echo_vtab *pVtab = (echo_vtab *)vtab;
+  Tcl_Interp *interp = pVtab->interp;
+  Tcl_CmdInfo info;
+  if( strcmp(zFuncName,"glob")!=0 ){
+    return 0;
+  }
+  if( Tcl_GetCommandInfo(interp, "::echo_glob_overload", &info)==0 ){
+    return 0;
+  }
+  *pxFunc = overloadedGlobFunction;
+  *ppArg = interp;
+  return 1;
+}
+
+/*
 ** A virtual table module that merely "echos" the contents of another
 ** table (like an SQL VIEW).
 */
@@ -919,7 +978,7 @@
   echoSync,                  /* xSync - sync transaction */
   echoCommit,                /* xCommit - commit transaction */
   echoRollback,              /* xRollback - rollback transaction */
-  0,                         /* xFindMethod - function overloading */
+  echoFindFunction,          /* xFindFunction - function overloading */
 };
 
 /*
diff --git a/src/vtab.c b/src/vtab.c
index 5a3a6d7..0f35af6 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to help implement virtual tables.
 **
-** $Id: vtab.c,v 1.26 2006/07/08 17:06:44 drh Exp $
+** $Id: vtab.c,v 1.27 2006/07/08 18:09:15 drh Exp $
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 #include "sqliteInt.h"
@@ -594,9 +594,8 @@
   Table *pTab;
   sqlite3_vtab *pVtab;
   sqlite3_module *pMod;
-  int (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+  void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
   void *pArg;
-  int iEnc;
   int rc;
   FuncDef *pNew;
 
@@ -614,7 +613,7 @@
  
   /* Call the xFuncFunction method on the virtual table implementation
   ** to see if the implementation wants to overload this function */
-  if( pMod->xFindFunction(pVtab, nArg, pDef->zName, &xFunc, &pArg, &iEnc)==0 ){
+  if( pMod->xFindFunction(pVtab, nArg, pDef->zName, &xFunc, &pArg)==0 ){
     return pDef;
   }
 
@@ -628,7 +627,6 @@
   strcpy(pNew->zName, pDef->zName);
   pNew->xFunc = xFunc;
   pNew->pUserData = pArg;
-  pNew->iPrefEnc = iEnc;
   pNew->flags |= SQLITE_FUNC_EPHEM;
   return pNew;
 }