aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/expr.c7
-rw-r--r--src/sqlite.h.in5
-rw-r--r--src/sqliteInt.h4
-rw-r--r--src/test8.c5
-rw-r--r--src/test_schema.c8
-rw-r--r--src/test_tclvar.c5
-rw-r--r--src/vdbeaux.c16
-rw-r--r--src/vtab.c62
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 */