]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Allow virtual table implementations to overload function that use
authordrh <drh@noemail.net>
Sat, 8 Jul 2006 17:06:43 +0000 (17:06 +0000)
committerdrh <drh@noemail.net>
Sat, 8 Jul 2006 17:06:43 +0000 (17:06 +0000)
a column of the virtual table as their first argument.  Untested. (CVS 3322)

FossilOrigin-Name: 12cc7af4b6b8b4f1a43d962fbafde8cba683a907

manifest
manifest.uuid
src/expr.c
src/sqlite.h.in
src/sqliteInt.h
src/test8.c
src/test_schema.c
src/test_tclvar.c
src/vdbeaux.c
src/vtab.c

index a7f419658e3e3d33ba2a039f0d119b36b7385109..a249723e661a57cda40b95121281d53f459e2e93 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Make\sthe\ssqlite3_enable_load_extension()\sinterface\saccessible\sfrom\sthe\nTCL\sbindings.\s(CVS\s3321)
-D 2006-07-06T17:08:48
+C Allow\svirtual\stable\simplementations\sto\soverload\sfunction\sthat\suse\na\scolumn\sof\sthe\svirtual\stable\sas\stheir\sfirst\sargument.\s\sUntested.\s(CVS\s3322)
+D 2006-07-08T17:06:44
 F Makefile.in 9c2a76055c305868cc5f5b73e29a252ff3632c0a
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -42,7 +42,7 @@ F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
 F src/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
 F src/delete.c 804384761144fe1a5035b99f4bd7d706976831bd
 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
-F src/expr.c 78b521337d628b1fd9d87b12dbbe771247aab585
+F src/expr.c acfc181c473ec87e332de04f60a1e8beaa5df877
 F src/func.c f357a81bcdd83684cb198a8ad96be1c21e29f85c
 F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185
 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
@@ -72,9 +72,9 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
 F src/select.c 380fa06c99ae01050c0054c4b1db91e9f1d8322d
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 359551ab5cdd8f8fe5f3fe170fd330b108b08d7d
-F src/sqlite.h.in a1ae5f372affd1313d9bea98155f01626f538fbd
+F src/sqlite.h.in 6d96fe902d2311e007ead5d52c9f0b9f5bdc5ad9
 F src/sqlite3ext.h c611255287e9a11ce4f1fe6251c2a0b9d32a828b
-F src/sqliteInt.h e07a49b3e349c2c5f1bcb7dd9371fc3faf5ba338
+F src/sqliteInt.h ea16faa3efec989f82b8ef778aca2867440cb817
 F src/table.c d8817f43a6c6bf139487db161760b9e1e02da3f1
 F src/tclsqlite.c 0220791dc66d287a7f199568393f04f3db24364b
 F src/test1.c 535294d7f21a4127082c4f7a57f225482df9cc36
@@ -84,13 +84,13 @@ F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
 F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
 F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de
 F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3
-F src/test8.c 6a4d1bd453cb708738d6262641abf80ac2d13a62
+F src/test8.c 32b800e733fc80c5d847b6d2a17d4c60b1c4418c
 F src/test_async.c e3deaedd4d86a56391b81808fde9e44fbd92f1d3
 F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
 F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
-F src/test_schema.c 02f182f156e8e431a9508184df5638b370850495
+F src/test_schema.c 8b2aaa9136edf3187a51166849c2de0aaaa27ce5
 F src/test_server.c a6460daed0b92ecbc2531b6dc73717470e7a648c
-F src/test_tclvar.c 0fe60a8a7358f99d5d0c08d6822bd5b1b39b4d58
+F src/test_tclvar.c 6611657977c69bccd32b4ff7ccfb221a403ca2f0
 F src/tokenize.c 7b448440dfd6e984d6bef7ac7fc60f1d26eaf8e7
 F src/trigger.c 0fc40125820409a6274834a6e04ad804d96e2793
 F src/update.c 951f95ef044cf6d28557c48dc35cb0711a0b9129
@@ -101,10 +101,10 @@ F src/vdbe.c 3ffc96ec2e870b3ab3e59d1f6fe34687e4ed1db6
 F src/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa
 F src/vdbeInt.h e3eaab262b67b84474625cfc38aec1125c32834b
 F src/vdbeapi.c 6af0e7160af260052a7a4500464221a03dada75f
-F src/vdbeaux.c bb0a7b800a7167f2e49702a2bfc971919c0b99d1
+F src/vdbeaux.c 51722bb3661f2d836c1a7a8e7eac242859ddbd07
 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
 F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
-F src/vtab.c 4751954e26e9caa6ce3ea5ad9468bd34f07d1de7
+F src/vtab.c 3fe6879f4a41606814a4eb2b9c0623fb1d2ab522
 F src/where.c 75a89957fcb8c068bec55caa4e9d2ed5fa0b0724
 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -375,7 +375,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 225a9597b21bde7666451fc2eb7695dc35c438bb
-R cceec30f57fbf4deae9e1f3246c140c4
+P ce96b890bbf2f2b9686e19bbb1111a70f6404cb5
+R e6cc629faa8ff4cdd0448656216aa349
 U drh
-Z 6a689bc7d7abe6c2c593a3ba21b7a44d
+Z d47bc48adf9981452a2ffd38517818f3
index 8d0dc865ef53bda1c3fe7b5b226bb01351a110ac..e79290a518cb3bc0d7aecaa09784bea37d02cff5 100644 (file)
@@ -1 +1 @@
-ce96b890bbf2f2b9686e19bbb1111a70f6404cb5
\ No newline at end of file
+12cc7af4b6b8b4f1a43d962fbafde8cba683a907
\ No newline at end of file
index 43e1c715e152887e2367cf714081ce42db7e03d8..66a7158e21bb006c204446f0e695c99c385caabf 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.262 2006/06/14 19:00:21 drh Exp $
+** $Id: expr.c,v 1.263 2006/07/08 17:06:44 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1674,6 +1674,11 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
       pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
       assert( pDef!=0 );
       nExpr = sqlite3ExprCodeExprList(pParse, pList);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+      if( nExpr>0 ){
+        pDef = sqlite3VtabOverloadFunction(pDef, nExpr, pList->a[0].pExpr);
+      }
+#endif
       for(i=0; i<nExpr && i<32; i++){
         if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
           constMask |= (1<<i);
index 6b179016b2cea0b140c844897b7685544e0ca69a..b5fce853d508661fa8de643b260e67d71d487ab7 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.185 2006/06/27 15:16:15 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.186 2006/07/08 17:06:44 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -1565,6 +1565,9 @@ struct sqlite3_module {
   int (*xSync)(sqlite3_vtab *pVTab);
   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);
 };
 
 /*
index 39876fefc101436f7778a7b21177cabf17f07a24..1beb79e93d7fdc22e0f46e5c1d3b47855719f5af 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.517 2006/06/27 15:16:15 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.518 2006/07/08 17:06:44 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -586,6 +586,7 @@ struct Module {
 */
 #define SQLITE_FUNC_LIKE   0x01  /* Candidate for the LIKE optimization */
 #define SQLITE_FUNC_CASE   0x02  /* Case-sensitive LIKE-type function */
+#define SQLITE_FUNC_EPHEM  0x04  /* Ephermeral.  Delete with VDBE */
 
 /*
 ** information about each column of an SQL table is held in an instance
@@ -1861,6 +1862,7 @@ int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
 int sqlite3VtabCallConnect(Parse*, Table*);
 int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
 int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *);
+FuncDef *sqlite3VtabOverloadFunction(FuncDef*, int nArg, Expr*);
 
 #ifdef SQLITE_SSE
 #include "sseInt.h"
index 179dc6d492e1a80e83226a04bb0c7c8c5aa9559b..bcacf980a31bc104d1bc54307351384b7e31d51c 100644 (file)
@@ -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.38 2006/06/26 19:10:32 drh Exp $
+** $Id: test8.c,v 1.39 2006/07/08 17:06:44 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -918,7 +918,8 @@ static sqlite3_module echoModule = {
   echoBegin,                 /* xBegin - begin transaction */
   echoSync,                  /* xSync - sync transaction */
   echoCommit,                /* xCommit - commit transaction */
-  echoRollback               /* xRollback - rollback transaction */
+  echoRollback,              /* xRollback - rollback transaction */
+  0,                         /* xFindMethod - function overloading */
 };
 
 /*
index 17818aea0e7edab1c9fdedd95de4006d1171dd1b..bd9083987a2f6820e736c8ada0b4ac4d826de409 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test_schema.c,v 1.8 2006/06/26 19:10:32 drh Exp $
+** $Id: test_schema.c,v 1.9 2006/07/08 17:06:44 drh Exp $
 */
 
 /* The code in this file defines a sqlite3 virtual-table module that
@@ -281,6 +281,12 @@ static sqlite3_module schemaModule = {
   schemaEof,                   /* xEof */
   schemaColumn,                /* xColumn - read data */
   schemaRowid,                 /* xRowid - read data */
+  0,                           /* xUpdate */
+  0,                           /* xBegin */
+  0,                           /* xSync */
+  0,                           /* xCommit */
+  0,                           /* xRollback */
+  0,                           /* xFindMethod */
 };
 
 
index ba233d15aae01ab6621514d03a6558602d6b2c24..025bc90265641445b917db314d5b456025c790df 100644 (file)
@@ -16,7 +16,7 @@
 ** The emphasis of this file is a virtual table that provides
 ** access to TCL variables.
 **
-** $Id: test_tclvar.c,v 1.6 2006/06/27 12:25:00 danielk1977 Exp $
+** $Id: test_tclvar.c,v 1.7 2006/07/08 17:06:44 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -267,7 +267,8 @@ static sqlite3_module tclvarModule = {
   0,                           /* xBegin */
   0,                           /* xSync */
   0,                           /* xCommit */
-  0                            /* xRollback */
+  0,                           /* xRollback */
+  0,                           /* xFindMethod */
 };
 
 /*
index 837aad25917f2dc2034bc3ea487ce7654396bb7d..f81a2cce66a5221d7b95db26f11385c87ddc1c81 100644 (file)
@@ -373,6 +373,17 @@ void sqlite3VdbeJumpHere(Vdbe *p, int addr){
   sqlite3VdbeChangeP2(p, addr, p->nOp);
 }
 
+
+/*
+** If the input FuncDef structure is ephemeral, then free it.  If
+** the FuncDef is not ephermal, then do nothing.
+*/
+static void freeEphemeralFunction(FuncDef *pDef){
+  if( pDef && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){
+    sqliteFree(pDef);
+  }
+}
+
 /*
 ** Delete a P3 value if necessary.
 */
@@ -391,10 +402,15 @@ static void freeP3(int p3type, void *p3){
       }
       case P3_VDBEFUNC: {
         VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
+        freeEphemeralFunction(pVdbeFunc->pFunc);
         sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
         sqliteFree(pVdbeFunc);
         break;
       }
+      case P3_FUNCDEF: {
+        freeEphemeralFunction((FuncDef*)p3);
+        break;
+      }
       case P3_MEM: {
         sqlite3ValueFree((sqlite3_value*)p3);
         break;
index f687a251f1bed169076f7d8783ab35021b9d8cc8..5a3a6d7464d8a510f13460b911ac99fef134fa27 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to help implement virtual tables.
 **
-** $Id: vtab.c,v 1.25 2006/06/26 11:17:51 danielk1977 Exp $
+** $Id: vtab.c,v 1.26 2006/07/08 17:06:44 drh Exp $
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 #include "sqliteInt.h"
@@ -573,4 +573,64 @@ int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){
   return rc;
 }
 
+/*
+** The first parameter (pDef) is a function implementation.  The
+** second parameter (pExpr) is the first argument to this function.
+** If pExpr is a column in a virtual table, then let the virtual
+** table implementation have an opportunity to overload the function.
+**
+** This routine is used to allow virtual table implementations to
+** overload MATCH, LIKE, GLOB, and REGEXP operators.
+**
+** Return either the pDef argument (indicating no change) or a 
+** new FuncDef structure that is marked as ephemeral using the
+** SQLITE_FUNC_EPHEM flag.
+*/
+FuncDef *sqlite3VtabOverloadFunction(
+  FuncDef *pDef,  /* Function to possibly overload */
+  int nArg,       /* Number of arguments to the function */
+  Expr *pExpr     /* First argument to the function */
+){
+  Table *pTab;
+  sqlite3_vtab *pVtab;
+  sqlite3_module *pMod;
+  int (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+  void *pArg;
+  int iEnc;
+  int rc;
+  FuncDef *pNew;
+
+  /* Check to see the left operand is a column in a virtual table */
+  if( pExpr==0 ) return pDef;
+  if( pExpr->op!=TK_COLUMN ) return pDef;
+  pTab = pExpr->pTab;
+  if( pTab==0 ) return pDef;
+  if( !pTab->isVirtual ) return pDef;
+  pVtab = pTab->pVtab;
+  assert( pVtab!=0 );
+  assert( pVtab->pModule!=0 );
+  pMod = pVtab->pModule;
+  if( pMod->xFindFunction==0 ) return pDef;
+  /* 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 ){
+    return pDef;
+  }
+
+  /* Create a new ephemeral function definition for the overloaded
+  ** function */
+  pNew = sqliteMalloc( sizeof(*pNew) + strlen(pDef->zName) );
+  if( pNew==0 ){
+    return pDef;
+  }
+  *pNew = *pDef;
+  strcpy(pNew->zName, pDef->zName);
+  pNew->xFunc = xFunc;
+  pNew->pUserData = pArg;
+  pNew->iPrefEnc = iEnc;
+  pNew->flags |= SQLITE_FUNC_EPHEM;
+  return pNew;
+}
+
 #endif /* SQLITE_OMIT_VIRTUALTABLE */