Index: src/sqlite.h.in ================================================================== --- src/sqlite.h.in +++ src/sqlite.h.in @@ -8035,10 +8035,24 @@ ** of the SQL statement that triggered the call to the [xUpdate] method of the ** [virtual table]. */ int sqlite3_vtab_on_conflict(sqlite3 *); +/* +** CAPI3REF: Determine The Collation For a Virtual Table Constraint +** +** This function may only be called from within a call to the [xBestIndex] +** method of a [virtual table implementation]. +** +** The first argument must be the database handle with which the virtual +** table is associated (the one passed to the [xConnect] or [xCreate] method +** to create the sqlite3_vtab object. The second argument must be an index +** into the aConstraint[] array belonging to the sqlite3_index_info structure +** passed to xBestIndex. This function returns a pointer to a buffer +** containing the name of the collation sequence for the corresponding +** constraint. +*/ SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3*, int); /* ** CAPI3REF: Conflict resolution modes ** KEYWORDS: {conflict resolution mode} Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -1397,11 +1397,11 @@ int nVTrans; /* Allocated size of aVTrans */ Hash aModule; /* populated by sqlite3_create_module() */ VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ VTable **aVTrans; /* Virtual tables with open transactions */ VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ - void *pVtabWC; /* For sqlite3_vtab_collation() */ + void *pBestIndexCtx; /* For sqlite3_vtab_collation() */ #endif Hash aFunc; /* Hash table of connection functions */ Hash aCollSeq; /* All collating sequences */ BusyHandler busyHandler; /* Busy callback */ Db aDbStatic[2]; /* Static space for the 2 default backends */ Index: src/where.c ================================================================== --- src/where.c +++ src/where.c @@ -3115,18 +3115,29 @@ return rc; } +/* +** Context object used to pass information from whereLoopAddVirtual() +** to sqlite3_vtab_collation(). +*/ struct BestIndexCtx { WhereClause *pWC; sqlite3_index_info *pIdxInfo; Parse *pParse; }; +/* +** If this function is invoked from within an xBestIndex() callback, it +** returns a pointer to a buffer containing the name of the collation +** sequence associated with element iCons of the sqlite3_index_info.aConstraint +** array. Or, if iCons is out of range or there is no active xBestIndex +** call, return NULL. +*/ const char *sqlite3_vtab_collation(sqlite3 *db, int iCons){ - struct BestIndexCtx *p = (struct BestIndexCtx*)db->pVtabWC; + struct BestIndexCtx *p = (struct BestIndexCtx*)db->pBestIndexCtx; const char *zRet = 0; if( p && iCons>=0 && iConspIdxInfo->nConstraint ){ int iTerm = p->pIdxInfo->aConstraint[iCons].iTermOffset; Expr *pX = p->pWC->a[iTerm].pExpr; CollSeq *pC = sqlite3BinaryCompareCollSeq(p->pParse,pX->pLeft,pX->pRight); @@ -3200,12 +3211,12 @@ } bic.pWC = pWC; bic.pIdxInfo = p; bic.pParse = pParse; - pSaved = pParse->db->pVtabWC; - pParse->db->pVtabWC = (void*)&bic; + pSaved = pParse->db->pBestIndexCtx; + pParse->db->pBestIndexCtx = (void*)&bic; /* First call xBestIndex() with all constraints usable. */ WHERETRACE(0x40, (" VirtualOne: all usable\n")); rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn); @@ -3279,11 +3290,11 @@ } } if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); sqlite3DbFreeNN(pParse->db, p); - pParse->db->pVtabWC = pSaved; + pParse->db->pBestIndexCtx = pSaved; return rc; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /*