diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 7 | ||||
-rw-r--r-- | src/sqlite.h.in | 5 | ||||
-rw-r--r-- | src/sqliteInt.h | 4 | ||||
-rw-r--r-- | src/test8.c | 5 | ||||
-rw-r--r-- | src/test_schema.c | 8 | ||||
-rw-r--r-- | src/test_tclvar.c | 5 | ||||
-rw-r--r-- | src/vdbeaux.c | 16 | ||||
-rw-r--r-- | src/vtab.c | 62 |
8 files changed, 103 insertions, 9 deletions
diff --git a/src/expr.c b/src/expr.c index 43e1c715e..66a7158e2 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 <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); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 6b179016b..b5fce853d 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.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); }; /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 39876fefc..1beb79e93 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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" diff --git a/src/test8.c b/src/test8.c index 179dc6d49..bcacf980a 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.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 */ }; /* diff --git a/src/test_schema.c b/src/test_schema.c index 17818aea0..bd9083987 100644 --- a/src/test_schema.c +++ b/src/test_schema.c @@ -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 */ }; diff --git a/src/test_tclvar.c b/src/test_tclvar.c index ba233d15a..025bc9026 100644 --- a/src/test_tclvar.c +++ b/src/test_tclvar.c @@ -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 */ }; /* diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 837aad259..f81a2cce6 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -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; diff --git a/src/vtab.c b/src/vtab.c index f687a251f..5a3a6d746 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 */ |