Experimental attempt to reduce reprepares caused by bound variables and "=" constraints in WHERE clauses.

FossilOrigin-Name: 1cfdde74f1c68589d722b876c20317c2a70cec2d915546a2200035190d3fb082
This commit is contained in:
dan committed 2026-08-18 18:22:47 +00:00
1 parent 9e5727e51d
commit c60dd4af07
9 files changed
+70 -19

No files matched your search

+14 -12
View File
@@ -1,5 +1,5 @@
C Correctly\sprocess\s"x\sIS\sTRUE"\sand\ssimilar\sexpressions\sthat\sappear\sin\sthe\ssecond\sor\slater\srows\sof\sa\sVALUES()\sclause.\sReport\s[bugs:/info/2026-08-18T05:06:40Z\s|\s2026-08-18T05:06:40Z].
D 2026-08-18T15:13:10.104
C Experimental\sattempt\sto\sreduce\sreprepares\scaused\sby\sbound\svariables\sand\s"="\sconstraints\sin\sWHERE\sclauses.
D 2026-08-18T18:22:47.790
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -811,10 +811,10 @@ F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
F src/util.c cfdf9c6e5323af886d5ce766709da607ba1d14193ad3a15f4f462a45420e8211
F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82
F src/vdbe.c 37ffba7c3fe3ed2c90dd8b889b0e1b957c337bf5ecdca49dac769e579b96ec9f
F src/vdbe.h 70e862ac8a11b590f8c1eaac17a0078429d42bc4ea3f757a9af0f451dd966a71
F src/vdbeInt.h 39f4c8eb1e4ac0593037d5268a54a691c72d34896db9973a9d39f2a5dea14163
F src/vdbeapi.c 6ad0c841b6cb87de068f71787f385149d794e8830176bf72d09a36b9f655ac5b
F src/vdbeaux.c 1e3fefcdf497d0240296de3064e3c85204c03ded23a9010417a57af51a2c560e
F src/vdbe.h 772a672b9f7dc3446b1233cf08016fa02b4e57736e21de1b625f924ee5743de3
F src/vdbeInt.h 2ab0984d970c9aa9dc5f861f4938e627137bf0122c61cd19e0a8e2c3b2704105
F src/vdbeapi.c f413302be2dfe6fd9b7397c5ef269ed34d51a47e48d8da406a618bbd99dbf6d2
F src/vdbeaux.c d1018b2442a6f14df8952702aa735a2c6540a99ef941cb8e060d75fb2b84a657
F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
F src/vdbemem.c 6e7ad67507c9a8e625b46256a9c003929331d6a27b99bbe139b8f0dab636e1f2
F src/vdbesort.c a72ad2a629df2901fde4aa588e38590d0aa27b7d5bc3b2a416e5f295de839cc1
@@ -825,7 +825,7 @@ F src/vxworks.h 9d18819c5235b49c2340a8a4d48195ec5d5afb637b152406de95a9436beeaeab
F src/wal.c cb28ab3a71cb73ea422a2fcc26283b65a1e5a2a65c44de86951c7d6a186381ac
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
F src/where.c 2f5b4091f37bfac7658ea3d52b2c192d8fb2ec062f232815e0eb5152a46267db
F src/where.c 1e688d7ca06f48104fa217d61f7864a471d400dd7c161cc0928ea4a23e1662c9
F src/whereInt.h f039ad303bc2913de673e431821ef8db3b619d249e6e5548d90072a684e72285
F src/wherecode.c aa733a45b550c65aae0641335ddd6179a24c6bf0889bf0dda44a8dddc74d6bb0
F src/whereexpr.c cd88bd3e1a421fb987eb5991ecf7a9a3d5dad1abb02a8baa070336b6dfa70b59
@@ -1594,7 +1594,7 @@ F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
F test/savepoint6.test 48a645a7bb3a59a6fcf06a7364cfe5b655c336760de39068f7c241b0fc80d963
F test/savepoint7.test 24c69af86d750c80d51cf6500fde9270717f2b6e5658f055b5e75af75d5af179
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
F test/scanstatus.test b249328caf4d317e71058006872b8012598a5fa045b30bf24a81eeff650ab49e
F test/scanstatus.test f5eccd84923bb2f19dad894ecbb9ec44ad9082e716d3f5c5618d9a3e8b20c377
F test/scanstatus2.test 1f0fcf71c6653435caa114a79588bdd146d4ceb5e9a4e1a7e449bf0643ed30f5
F test/schema.test e615575f2d756df4629596523f11d9322384ecf9f980e58c774cff80ff041c33
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
@@ -2219,9 +2219,11 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
P 08e5a730d4ccfba16e961550a232512a956f0f2f9116a2e59e4a2124c3277915 0de50d5685b2edf317bdc48f79052f58a64738d3ee966ad1e631f76f4aba6168
R 04d586313750ba0ac5176c8f7c20409d
T +closed 0de50d5685b2edf317bdc48f79052f58a64738d3ee966ad1e631f76f4aba6168
P d287358b8d356d4fd3643b6776c56c6a6fdfb175834351eaed0148db4079dc67
R 7b40db5f79b899d44c32b421bb859cb8
T *branch * reduce-reprepares
T *sym-reduce-reprepares *
T -sym-trunk *
U dan
Z a67f08c32f6d4593019e9b394667875d
Z 072b1ba5ace1e3a1e224512341b20686
# Remove this line to create a well-formed Fossil manifest.
+2 -2
View File
@@ -1,2 +1,2 @@
branch trunk
tag trunk
branch reduce-reprepares
tag reduce-reprepares
+1 -1
View File
@@ -1 +1 @@
d287358b8d356d4fd3643b6776c56c6a6fdfb175834351eaed0148db4079dc67
1cfdde74f1c68589d722b876c20317c2a70cec2d915546a2200035190d3fb082
+2
View File
@@ -297,6 +297,8 @@ void sqlite3VdbeSwap(Vdbe*,Vdbe*);
VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
void sqlite3VdbeSetVarmask(Vdbe*, int);
u32 sqlite3VdbeGetVarmask(Vdbe *v);
void sqlite3VdbeSetSmallint(Vdbe*, u32);
#ifndef SQLITE_OMIT_TRACE
char *sqlite3VdbeExpandSql(Vdbe*, const char*);
#endif
+1
View File
@@ -520,6 +520,7 @@ struct Vdbe {
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
int nFrame; /* Number of frames in pFrame list */
u32 expmask; /* Binding to these vars invalidates VM */
u32 smimask; /* Binding 0 or 1 to these vars invalidates VM */
SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
AuxData *pAuxData; /* Linked list of auxdata allocations */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+8
View File
@@ -1856,6 +1856,14 @@ int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
if( rc==SQLITE_OK ){
assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
/* If the bit corresponding to this variable is set in smimask, and the
** value bound was 0 or 1, recompile the statement. */
if( (iValue==0 || iValue==1)
&& (p->smimask & (i>=32 ? 0x80000000 : (u32)1<<(i-1)))!=0
){
p->expired = 1;
}
sqlite3_mutex_leave(p->db->mutex);
}
return rc;
+29
View File
@@ -5342,6 +5342,35 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
}
}
/*
** Return the current value of expmask - the mask of variables for which
** binding a new value forces repreparation of the statement.
*/
u32 sqlite3VdbeGetVarmask(Vdbe *v){
return v->expmask;
}
/*
** This is called to configure an SQL variable so that the statement is
** reprepared if a small integer value (0 or 1) is bound to it.
**
** To use this function, the current value of expmask is obtained via
** sqlite3VdbeGetVarmask(). This value should be passed as the second
** parameter to this function. Then some sub-routine is called that may
** make a call to sqlite3VdbeSetVarmask(). Finally, this routine is called.
** If sqlite3VdbeSetVarmask was called, then the variable that it marked
** as causing repreparation is modified to that it only causes a reprepare
** if a small integer value is bound to it.
**
** u32 mask = sqlite3VdbeGetVarmask();
** sqlite3VdbeSetVarmask(v, iVar); // mark iVar as causing repreparation
** sqlite3VdbeSetSmallint(v, mask); // but only for small integer values
*/
void sqlite3VdbeSetSmallint(Vdbe *v, u32 expmask){
v->smimask |= (v->expmask ^ expmask);
v->expmask = expmask;
}
/*
** Helper function for vdbeIsMatchingIndexKey(). Return true if column
** iCol should be ignored when comparing a record with a record from
+9
View File
@@ -3042,6 +3042,13 @@ static void whereLoopOutputAdjust(
int i, j;
LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */
/* Skip all this if the FROM clause of the query is a single table and
** there is no ORDER BY. In this case it doesn't matter how accurate
** the WhereLoop.nOut values are. */
if( pWC->pWInfo->pTabList->nSrc<=1 && pWC->pWInfo->pOrderBy==0 ){
return;
}
assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){
assert( pTerm!=0 );
@@ -3088,10 +3095,12 @@ static void whereLoopOutputAdjust(
Expr *pRight = pOpExpr->pRight;
Parse *pParse = pWC->pWInfo->pParse;
int k = 0;
u32 expmask = sqlite3VdbeGetVarmask(pParse->pVdbe);
testcase( pOpExpr->op==TK_IS );
if( sqlite3ExprIsInteger(pRight, &k, pParse) && k>=(-1) && k<=1 ){
k = 10;
}else{
sqlite3VdbeSetSmallint(pParse->pVdbe, expmask);
k = 20;
}
if( iReduce<k ){
+4 -4
View File
@@ -168,7 +168,7 @@ do_execsql_test 2.8.1 {
SELECT * FROM x2 WHERE i=1 AND j='two'
}
do_scanstatus_test 2.8.2 {
nLoop 1 nVisit 0 nEst 8.0 zName x2ij
nLoop 1 nVisit 0 nEst 9.0 zName x2ij
zExplain {SEARCH x2 USING INDEX x2ij (i=? AND j=?)}
}
@@ -176,7 +176,7 @@ do_execsql_test 2.9.1 {
SELECT * FROM x2 WHERE i=5 AND j='two'
}
do_scanstatus_test 2.9.2 {
nLoop 1 nVisit 0 nEst 8.0 zName x2ij
nLoop 1 nVisit 0 nEst 9.0 zName x2ij
zExplain {SEARCH x2 USING INDEX x2ij (i=? AND j=?)}
}
@@ -184,7 +184,7 @@ do_execsql_test 2.10.1 {
SELECT * FROM x2 WHERE i=3 AND j='three'
} {3 three {3 three}}
do_scanstatus_test 2.10.2 {
nLoop 1 nVisit 1 nEst 8.0 zName x2ij
nLoop 1 nVisit 1 nEst 9.0 zName x2ij
zExplain {SEARCH x2 USING INDEX x2ij (i=? AND j=?)}
}
@@ -279,7 +279,7 @@ do_scanstatus_test 4.2.2 {
nLoop 1 nVisit 1 nEst 1.0 zName sqlite_autoindex_p1_1
zExplain {SEARCH p1 USING INDEX sqlite_autoindex_p1_1 (x=?)}
nLoop 1 nVisit 3 nEst 262144.0 zName c1 zExplain {SCAN c1}
nLoop 1 nVisit 3 nEst 1048576.0 zName c1 zExplain {SCAN c1}
}
#-------------------------------------------------------------------------