Add some support for OR terms to sqlite3_whereinfo_hook().
FossilOrigin-Name: 5cd070000da1d9e399090677b4db75dc5639c33211385d6eb84f14a4d0b617cd
This commit is contained in:
parent
e86573fa51
commit
53761f4d52
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C Add\sthe\ssqlite3_whereinfo_hook()\sAPI\s-\san\sexperimental\sAPI\sreplacing\sthe\nDBCONFIG_WHEREINFO\shack\son\sthis\sbranch.
|
||||
D 2017-04-04T04:23:06.108
|
||||
C Add\ssome\ssupport\sfor\sOR\sterms\sto\ssqlite3_whereinfo_hook().
|
||||
D 2017-04-04T17:50:31.913
|
||||
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a
|
||||
@ -403,7 +403,7 @@ F src/resolve.c 3e518b962d932a997fae373366880fc028c75706
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa
|
||||
F src/shell.c e524688c2544167f835ba43e24309f8707ca60c8ab6eb5c263a12c8618a233b8
|
||||
F src/shell_indexes.c 12cc58b62492bddc88f879086b4cd1045dbfd4e52040ecb6c39b971a6aac80ba
|
||||
F src/shell_indexes.c d40ea0a81112df7bdccd7232238bee0bbb39699085ea78cc08fd863bf052a63b
|
||||
F src/sqlite.h.in ae5c9cbf2e77492c319fca08769575d9695e64718a16d32324944d24e291bcf7
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28
|
||||
@ -483,7 +483,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344
|
||||
F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
|
||||
F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791
|
||||
F src/where.c cbd1e8562fa37de359963749e1dc3d0dd1a42a894d10a62928bffc709490fde6
|
||||
F src/where.c be352441558b55e21964ff53f0483776594789d0ede12dd9c58b022873c858f8
|
||||
F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4
|
||||
F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04
|
||||
F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c
|
||||
@ -1120,7 +1120,7 @@ F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1
|
||||
F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
|
||||
F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9
|
||||
F test/shell6.test 05c2488ff2bb11ac300b9170e8f5b6e03d58982c77035cdca5dbf036f0d3c5b7
|
||||
F test/shell6.test 081067c1afcb38da50134ffd5ccc0a59ede14f41959486f733ffbba689c0ccfa
|
||||
F test/shell7.test 07751911b294698e0c5df67bcbd29e7d2f0f2907
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
@ -1571,7 +1571,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P cb721d0b36268a7b0ef493fa4d7f6bcbaa9ead8b1990e3c3fae015fa1d545226
|
||||
R 061e66f6528edc67cfbe5cb82be7b02d
|
||||
P a54aef35da11f7508a8888a159372036a362fc52afa1df752dc835db334c4330
|
||||
R 51e547bc1c25ea79dd375d8f020224f3
|
||||
U dan
|
||||
Z d08fd2524fbe07ca7104a150ba1edcbe
|
||||
Z fe378068686ea107c39185021a17b4ae
|
||||
|
@ -1 +1 @@
|
||||
a54aef35da11f7508a8888a159372036a362fc52afa1df752dc835db334c4330
|
||||
5cd070000da1d9e399090677b4db75dc5639c33211385d6eb84f14a4d0b617cd
|
@ -175,9 +175,6 @@ static void idxWhereInfo(
|
||||
eOp==SQLITE_WHEREINFO_EQUALS ? "EQUALS" :
|
||||
eOp==SQLITE_WHEREINFO_RANGE ? "RANGE" :
|
||||
eOp==SQLITE_WHEREINFO_ORDERBY ? "ORDERBY" :
|
||||
eOp==SQLITE_WHEREINFO_NEXTOR ? "NEXTOR" :
|
||||
eOp==SQLITE_WHEREINFO_ENDOR ? "ENDOR" :
|
||||
eOp==SQLITE_WHEREINFO_BEGINOR ? "BEGINOR" :
|
||||
"!error!";
|
||||
printf("op=%s zVal=%s iVal=%d mask=%llx\n", zOp, zVal, iVal, mask);
|
||||
#endif
|
||||
@ -630,7 +627,9 @@ static int idxCreateFromCons(
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
rc = sqlite3_exec(dbm, zIdx, 0, 0, pCtx->pzErrmsg);
|
||||
/* printf("%s\n", zIdx); */
|
||||
#if 0
|
||||
printf("CANDIDATE: %s\n", zIdx);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK && pCtx->iIdxRowid==0 ){
|
||||
|
117
src/where.c
117
src/where.c
@ -4278,6 +4278,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_WHEREINFO_HOOK
|
||||
|
||||
static void whereTraceWC(
|
||||
Parse *pParse,
|
||||
struct SrcList_item *pItem,
|
||||
@ -4285,7 +4286,7 @@ static void whereTraceWC(
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
Table *pTab = pItem->pTab;
|
||||
void (*x)(void*, int, const char*, int, i64) = db->xWhereInfo;
|
||||
void (*x)(void*, int, const char*, int, u64) = db->xWhereInfo;
|
||||
void *pCtx = db->pWhereInfoCtx;
|
||||
int ii;
|
||||
|
||||
@ -4311,6 +4312,109 @@ static void whereTraceWC(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If there are any OR terms in WHERE clause pWC, make the associated
|
||||
** where-info hook callbacks.
|
||||
*/
|
||||
static void whereTraceOR(
|
||||
Parse *pParse,
|
||||
struct SrcList_item *pItem,
|
||||
WhereClause *pWC
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
WhereClause tempWC;
|
||||
struct TermAndIdx {
|
||||
WhereTerm *pTerm;
|
||||
int iIdx;
|
||||
} aOr[4];
|
||||
int nOr = 0;
|
||||
Table *pTab = pItem->pTab;
|
||||
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
|
||||
int ii;
|
||||
|
||||
memset(aOr, 0, sizeof(aOr));
|
||||
|
||||
/* Iterate through OR nodes */
|
||||
for(ii=0; ii<pWC->nTerm; ii++){
|
||||
WhereTerm *pTerm = &pWC->a[ii];
|
||||
if( pTerm->eOperator & WO_OR ){
|
||||
/* Check that each branch of this OR term contains at least
|
||||
** one reference to the table currently being processed. If that
|
||||
** is not the case, this term can be ignored. */
|
||||
WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
|
||||
WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
|
||||
WhereTerm *pOrTerm;
|
||||
WhereClause *pTermWC;
|
||||
WhereScan scan;
|
||||
|
||||
for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
|
||||
int iCol;
|
||||
if( (pOrTerm->eOperator & WO_AND)!=0 ){
|
||||
pTermWC = &pOrTerm->u.pAndInfo->wc;
|
||||
}else{
|
||||
tempWC.pWInfo = pWC->pWInfo;
|
||||
tempWC.pOuter = pWC;
|
||||
tempWC.op = TK_AND;
|
||||
tempWC.nTerm = 1;
|
||||
tempWC.a = pOrTerm;
|
||||
pTermWC = &tempWC;
|
||||
}
|
||||
|
||||
for(iCol=0; iCol<pTab->nCol; iCol++){
|
||||
int iCsr = pItem->iCursor;
|
||||
if( !whereScanInit(&scan, pTermWC, iCsr, iCol, WO_SINGLE, 0) ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( iCol==pTab->nCol ) break;
|
||||
}
|
||||
|
||||
if( pOrTerm==pOrWCEnd ){
|
||||
aOr[nOr].pTerm = pTerm;
|
||||
aOr[nOr].iIdx = pOrWC->nTerm;
|
||||
nOr++;
|
||||
if( nOr==ArraySize(aOr) ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while( 1 ){
|
||||
for(ii=0; ii<nOr; ii++){
|
||||
if( aOr[ii].iIdx==0 ){
|
||||
aOr[ii].iIdx = aOr[ii].pTerm->u.pOrInfo->wc.nTerm;
|
||||
}else{
|
||||
aOr[ii].iIdx--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ii==nOr ) break;
|
||||
|
||||
/* Table name callback */
|
||||
db->xWhereInfo(db->pWhereInfoCtx,
|
||||
SQLITE_WHEREINFO_TABLE, pTab->zName, iDb, pItem->colUsed
|
||||
);
|
||||
/* whereTraceWC(pParse, pItem, pWC); */
|
||||
for(ii=0; ii<nOr; ii++){
|
||||
WhereClause * const pOrWC = &aOr[ii].pTerm->u.pOrInfo->wc;
|
||||
if( aOr[ii].iIdx<pOrWC->nTerm ){
|
||||
WhereClause *pTermWC;
|
||||
WhereTerm *pOrTerm = &pOrWC->a[aOr[ii].iIdx];
|
||||
if( (pOrTerm->eOperator & WO_AND)!=0 ){
|
||||
pTermWC = &pOrTerm->u.pAndInfo->wc;
|
||||
}else{
|
||||
tempWC.pWInfo = pWC->pWInfo;
|
||||
tempWC.pOuter = pWC;
|
||||
tempWC.op = TK_AND;
|
||||
tempWC.nTerm = 1;
|
||||
tempWC.a = pOrTerm;
|
||||
pTermWC = &tempWC;
|
||||
}
|
||||
whereTraceWC(pParse, pItem, pTermWC);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If there is a where-info hook attached to the database handle, issue all
|
||||
** required callbacks for the current sqlite3WhereBegin() call.
|
||||
@ -4321,16 +4425,16 @@ static void whereTraceBuilder(
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
if( db->xWhereInfo && db->init.busy==0 ){
|
||||
void (*x)(void*, int, const char*, int, i64) = db->xWhereInfo;
|
||||
void (*x)(void*, int, const char*, int, u64) = db->xWhereInfo;
|
||||
void *pCtx = db->pWhereInfoCtx;
|
||||
int ii;
|
||||
int nTab = p->pWInfo->pTabList->nSrc;
|
||||
SrcList *pTabList = p->pWInfo->pTabList;
|
||||
|
||||
/* Loop through each element of the FROM clause. Ignore any sub-selects
|
||||
** or views. Invoke the xWhereInfo() callback multiple times for each
|
||||
** real table. */
|
||||
for(ii=0; ii<p->pWInfo->pTabList->nSrc; ii++){
|
||||
struct SrcList_item *pItem = &p->pWInfo->pTabList->a[ii];
|
||||
for(ii=0; ii<pTabList->nSrc; ii++){
|
||||
struct SrcList_item *pItem = &pTabList->a[ii];
|
||||
if( pItem->pSelect==0 ){
|
||||
Table *pTab = pItem->pTab;
|
||||
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
|
||||
@ -4357,6 +4461,9 @@ static void whereTraceBuilder(
|
||||
|
||||
/* WHERE callbacks */
|
||||
whereTraceWC(pParse, pItem, p->pWC);
|
||||
|
||||
/* OR-clause processing */
|
||||
whereTraceOR(pParse, pItem, p->pWC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -188,4 +188,18 @@ do_setup_rec_test 10.1 {
|
||||
0|1|0|SEARCH TABLE t5 USING COVERING INDEX t5_idx_000123a7 (a=? AND b=?)
|
||||
}
|
||||
|
||||
# OR terms.
|
||||
#
|
||||
do_setup_rec_test 11.1 {
|
||||
CREATE TABLE t7(a, b);
|
||||
} {
|
||||
SELECT * FROM t7 WHERE a=? OR b=?
|
||||
} {
|
||||
CREATE INDEX t7_idx_00000061 ON t7(a)
|
||||
CREATE INDEX t7_idx_00000062 ON t7(b)
|
||||
0|0|0|SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?)
|
||||
0|0|0|SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user