aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanielk1977 <danielk1977@noemail.net>2006-06-13 15:00:54 +0000
committerdanielk1977 <danielk1977@noemail.net>2006-06-13 15:00:54 +0000
commitbe8a7835ea596518d5113fbf8b60d0780430ca7e (patch)
treea4782bc053afb1b11f68f50f098a6f1b433ed0fd /src
parent5fac9f86ebabe619e852f5aee1abba0047de083f (diff)
downloadsqlite-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.in16
-rw-r--r--src/test8.c24
-rw-r--r--src/vdbe.c14
-rw-r--r--src/vtab.c13
-rw-r--r--src/where.c16
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);