diff options
author | danielk1977 <danielk1977@noemail.net> | 2006-06-13 15:00:54 +0000 |
---|---|---|
committer | danielk1977 <danielk1977@noemail.net> | 2006-06-13 15:00:54 +0000 |
commit | be8a7835ea596518d5113fbf8b60d0780430ca7e (patch) | |
tree | a4782bc053afb1b11f68f50f098a6f1b433ed0fd /src | |
parent | 5fac9f86ebabe619e852f5aee1abba0047de083f (diff) | |
download | sqlite-be8a7835ea596518d5113fbf8b60d0780430ca7e.tar.gz sqlite-be8a7835ea596518d5113fbf8b60d0780430ca7e.zip |
Add the tentative sqlite3_allocate_queryplan() API. (CVS 3228)
FossilOrigin-Name: 7a3e97f76b1f4f97a04f7c5a9daa400402b2ff25
Diffstat (limited to 'src')
-rw-r--r-- | src/sqlite.h.in | 16 | ||||
-rw-r--r-- | src/test8.c | 24 | ||||
-rw-r--r-- | src/vdbe.c | 14 | ||||
-rw-r--r-- | src/vtab.c | 13 | ||||
-rw-r--r-- | src/where.c | 16 |
5 files changed, 60 insertions, 23 deletions
diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 023c90fff..f21438038 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.172 2006/06/13 14:16:59 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.173 2006/06/13 15:00:55 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -1547,7 +1547,7 @@ struct sqlite3_module { int (*xDestroy)(sqlite3_vtab *pVTab); int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); int (*xClose)(sqlite3_vtab_cursor*); - int (*xFilter)(sqlite3_vtab_cursor*, int idx, + int (*xFilter)(sqlite3_vtab_cursor*, char *zPlan, int nPlan, int argc, sqlite3_value **argv); int (*xNext)(sqlite3_vtab_cursor*); int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); @@ -1626,7 +1626,10 @@ struct sqlite3_index_info { int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ } *const aConstraintUsage; - int idxNum; /* Index number passed to xFilter */ + + char *zPlan; /* xBestIndex blob passed to xFilter */ + int nPlan; /* Size of nPlan */ + int orderByConsumed; /* True if output is already ordered */ double estimatedCost; /* Estimated cost of using this index */ }; @@ -1683,6 +1686,13 @@ struct sqlite3_vtab_cursor { int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); /* +** This function is called by the xBestIndex method of a module to +** allocate space to store the query-plan passed to the corresponding +** xFilter invocation(s). +*/ +char *sqlite3_allocate_queryplan(sqlite3_index_info *, int); + +/* ** The interface to the virtual-table mechanism defined above (back up ** to a comment remarkably similar to this one) is currently considered ** to be experimental. The interface might change in incompatible ways. diff --git a/src/test8.c b/src/test8.c index d95401ae5..5f005e03c 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.9 2006/06/13 14:16:59 danielk1977 Exp $ +** $Id: test8.c,v 1.10 2006/06/13 15:00:55 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -344,21 +344,19 @@ static int echoRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ static int echoFilter( sqlite3_vtab_cursor *pVtabCursor, - int idx, + char *zPlan, int nPlan, int argc, sqlite3_value **argv ){ int rc; - char zBuf[32]; int ii; echo_cursor *pCur = (echo_cursor *)pVtabCursor; echo_vtab *pVtab = (echo_vtab *)pVtabCursor->pVtab; sqlite3 *db = pVtab->db; - sprintf(zBuf, "%d", idx); appendToEchoModule(pVtab->interp, "xFilter"); - appendToEchoModule(pVtab->interp, zBuf); + appendToEchoModule(pVtab->interp, zPlan); for(ii=0; ii<argc; ii++){ appendToEchoModule(pVtab->interp, sqlite3_value_text(argv[ii])); } @@ -390,6 +388,8 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int ii; char *zWhere = 0; char *zOrder = 0; + char *zPlan = 0; + int nPlan = 0; int nArg = 0; echo_vtab *pVtab = (echo_vtab *)tab; @@ -435,10 +435,22 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ appendToEchoModule(pVtab->interp, zWhere); appendToEchoModule(pVtab->interp, zOrder); + nPlan = 2; + if( zWhere ){ + nPlan += strlen(zWhere); + } + if( zOrder ){ + nPlan += strlen(zWhere); + } + zPlan = sqlite3_allocate_queryplan(pIdxInfo, nPlan); + if( zPlan ){ + sprintf(zPlan, "%s%s%s", + zWhere?zWhere:"", (zOrder&&zWhere)?" ":"", zOrder?zOrder:""); + } + sqliteFree(zWhere); sqliteFree(zOrder); - pIdxInfo->idxNum = 123; return SQLITE_OK; } diff --git a/src/vdbe.c b/src/vdbe.c index 26caf2edb..22967d41f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.556 2006/06/13 14:16:59 danielk1977 Exp $ +** $Id: vdbe.c,v 1.557 2006/06/13 15:00:55 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -4596,20 +4596,19 @@ case OP_VOpen: { ** P3 points to enough free space to use to marshall the arguments. ** ** This opcode invokes the xFilter method on the virtual table specified -** by P1. The index number parameter to xFilter is the top of the stack. +** by P1. The query plan parameter to xFilter is the top of the stack. ** Next down on the stack is the argc parameter. Beneath the ** next of stack are argc additional parameters which are passed to ** xFilter as argv. The topmost parameter (i.e. 3rd element popped from ** the stack) becomes argv[argc-1] when passed to xFilter. ** -** The index number, argc, and all argv stack values are popped from the +** The query plan, argc, and all argv stack values are popped from the ** stack before this instruction completes. ** ** A jump is made to P2 if the result set after filtering would be ** empty. */ case OP_VFilter: { - int iIndex; int nArg; const sqlite3_module *pModule; @@ -4620,21 +4619,20 @@ case OP_VFilter: { /* Grab the index number and argc parameters off the top of the stack. */ assert( (&pTos[-1])>=p->aStack ); - assert( pTos[0].flags==MEM_Int && pTos[-1].flags==MEM_Int ); - iIndex = pTos[0].i; + assert( pTos[0].flags&MEM_Blob && pTos[-1].flags==MEM_Int ); nArg = pTos[-1].i; /* Invoke the xFilter method if one is defined. */ if( pModule->xFilter ){ int res; int ii; - Mem **apArg = pOp->p3; + Mem **apArg = (Mem **)pOp->p3; for(ii = 0; ii<nArg; ii++){ apArg[ii] = &pTos[ii+1-2-nArg]; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - res = pModule->xFilter(pCur->pVtabCursor, iIndex, nArg, apArg); + res = pModule->xFilter(pCur->pVtabCursor, pTos->z, pTos->n, nArg, apArg); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( res==0 ){ diff --git a/src/vtab.c b/src/vtab.c index 8c8ba246d..f717831ff 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.6 2006/06/13 10:24:43 danielk1977 Exp $ +** $Id: vtab.c,v 1.7 2006/06/13 15:00:55 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" @@ -278,6 +278,17 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ } /* +** Resize pInfo->zPlan to nBytes bytes using realloc(). Set pInfo->nPlan +** to nBytes and return a pointer to the allocated memory. +*/ +char *sqlite3_allocate_queryplan(sqlite3_index_info *pInfo, int nBytes){ + pInfo->nPlan = nBytes; + sqlite3ReallocOrFree(&pInfo->zPlan, nBytes); + return pInfo->zPlan; +} + + +/* ** This function is used to set the schema of a virtual table. It is only ** valid to call this function from within the xCreate() or xConnect() of a ** virtual table module. diff --git a/src/where.c b/src/where.c index 2a047d5c1..99edb3f5c 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.213 2006/06/13 14:16:59 danielk1977 Exp $ +** $Id: where.c,v 1.214 2006/06/13 15:00:55 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -1005,7 +1005,8 @@ static double bestVirtualIndex( pIdxCons->usable = (pTerm->prereqRight & notReady)==0; } memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); - pIdxInfo->idxNum = 0; + pIdxInfo->zPlan = 0; + pIdxInfo->nPlan = 0; pIdxInfo->orderByConsumed = 0; pIdxInfo->estimatedCost = SQLITE_BIG_DBL; nOrderBy = pIdxInfo->nOrderBy; @@ -1468,6 +1469,9 @@ static void whereInfoFree(WhereInfo *pWInfo){ if( pWInfo ){ int i; for(i=0; i<pWInfo->nLevel; i++){ + if( pWInfo->a[i].pIdxInfo ){ + sqliteFree(pWInfo->a[i].pIdxInfo->zPlan); + } sqliteFree(pWInfo->a[i].pIdxInfo); } sqliteFree(pWInfo); @@ -1754,8 +1758,8 @@ WhereInfo *sqlite3WhereBegin( } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( pLevel->pIdxInfo ){ - zMsg = sqlite3MPrintf("%z VIRTUAL TABLE INDEX %d", - pLevel->pIdxInfo->idxNum); + zMsg = sqlite3MPrintf("%z VIRTUAL TABLE INDEX %s", + pLevel->pIdxInfo->zPlan); } #endif if( pLevel->flags & WHERE_ORDERBY ){ @@ -1858,7 +1862,9 @@ WhereInfo *sqlite3WhereBegin( if( j==pIdxInfo->nConstraint ) break; } sqlite3VdbeAddOp(v, OP_Integer, i-1, 0); - sqlite3VdbeAddOp(v, OP_Integer, pIdxInfo->idxNum, 0); + sqlite3VdbeAddOp(v, OP_Blob, pIdxInfo->nPlan, 0); + sqlite3VdbeChangeP3(v, -1, pIdxInfo->zPlan, P3_DYNAMIC); + pIdxInfo->zPlan = 0; sqlite3VdbeAddOp(v, OP_VFilter, iCur, brk); zSpace = (char *)sqliteMalloc(sizeof(sqlite3_value*)*(i-1)); sqlite3VdbeChangeP3(v, -1, zSpace, P3_DYNAMIC); |