diff --git a/manifest b/manifest index a7f419658e..a249723e66 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 8d0dc865ef..e79290a518 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ce96b890bbf2f2b9686e19bbb1111a70f6404cb5 \ No newline at end of file +12cc7af4b6b8b4f1a43d962fbafde8cba683a907 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 43e1c715e1..66a7158e21 100644 --- a/src/expr.c +++ b/src/expr.c @@ -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 @@ -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; ia[i].pExpr) ){ constMask |= (1<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; diff --git a/src/vtab.c b/src/vtab.c index f687a251f1..5a3a6d7464 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.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 */