1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-16 23:02:26 +03:00

Initial implementation of the sqlite3_vtab_rhs_value() interface and the

qpvtab extension used for testing the virtual table interface.

FossilOrigin-Name: 0873c76b9b96b66fa9d13ddc8bca126d575ea3352349c7fd648f0c2f75d770f5
This commit is contained in:
drh
2022-01-20 17:10:59 +00:00
parent f208abdd99
commit 82801a5b72
11 changed files with 446 additions and 21 deletions

View File

@@ -30,8 +30,11 @@
*/
typedef struct HiddenIndexInfo HiddenIndexInfo;
struct HiddenIndexInfo {
WhereClause *pWC; /* The Where clause being analyzed */
Parse *pParse; /* The parsing context */
WhereClause *pWC; /* The Where clause being analyzed */
Parse *pParse; /* The parsing context */
sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST
** because extra space is allocated to hold up
** to nTerm such values */
};
/* Forward declaration of methods */
@@ -1095,7 +1098,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
/*
** Allocate and populate an sqlite3_index_info structure. It is the
** responsibility of the caller to eventually release the structure
** by passing the pointer returned by this function to sqlite3_free().
** by passing the pointer returned by this function to freeIndexInfo().
*/
static sqlite3_index_info *allocateIndexInfo(
Parse *pParse, /* The parsing context */
@@ -1207,13 +1210,14 @@ static sqlite3_index_info *allocateIndexInfo(
*/
pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
+ (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
+ sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) );
+ sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden)
+ sizeof(sqlite3_value*)*nTerm );
if( pIdxInfo==0 ){
sqlite3ErrorMsg(pParse, "out of memory");
return 0;
}
pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1];
pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1];
pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm];
pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
pIdxInfo->aConstraint = pIdxCons;
@@ -1278,6 +1282,24 @@ static sqlite3_index_info *allocateIndexInfo(
return pIdxInfo;
}
/*
** Free an sqlite3_index_info structure allocated by allocateIndexInfo()
** and possibly modified by xBestIndex methods.
*/
static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){
HiddenIndexInfo *pHidden;
int i;
assert( pIdxInfo!=0 );
pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
assert( pHidden->pParse!=0 );
assert( pHidden->pParse->db==db );
for(i=0; i<pIdxInfo->nConstraint; i++){
sqlite3ValueFree(pHidden->aRhs[i]);
pHidden->aRhs[i] = 0;
}
sqlite3DbFree(db, pIdxInfo);
}
/*
** The table object reference passed as the second argument to this function
** must represent a virtual table. This function invokes the xBestIndex()
@@ -3633,6 +3655,36 @@ const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){
return zRet;
}
/*
** This interface is callable from within the xBestIndex callback only.
**
** If possible, set (*ppVal) to point to an object containing the value
** on the right-hand-side of constraint iCons.
*/
int sqlite3_vtab_rhs_value(
sqlite3_index_info *pIdxInfo, /* Copy of first argument to xBestIndex */
int iCons, /* Constraint for which RHS is wanted */
sqlite3_value **ppVal /* Write value extracted here */
){
HiddenIndexInfo *pH = (HiddenIndexInfo*)&pIdxInfo[1];
sqlite3_value *pVal = 0;
int rc = SQLITE_OK;
if( iCons<0 || iCons>=pIdxInfo->nConstraint ){
rc = SQLITE_MISUSE;
}else{
if( pH->aRhs[iCons]==0 ){
WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset];
rc = sqlite3ValueFromExpr(
pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db),
SQLITE_AFF_BLOB, &pH->aRhs[iCons]
);
}
pVal = pH->aRhs[iCons];
}
*ppVal = pVal;
return rc;
}
/*
** Add all WhereLoop objects for a table of the join identified by
** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
@@ -3691,7 +3743,7 @@ static int whereLoopAddVirtual(
pNew->u.vtab.needFree = 0;
nConstraint = p->nConstraint;
if( whereLoopResize(pParse->db, pNew, nConstraint) ){
sqlite3DbFree(pParse->db, p);
freeIndexInfo(pParse->db, p);
return SQLITE_NOMEM_BKPT;
}
@@ -3771,7 +3823,7 @@ static int whereLoopAddVirtual(
}
if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
sqlite3DbFreeNN(pParse->db, p);
freeIndexInfo(pParse->db, p);
WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
return rc;
}