Enhance the integer-comparison optimization on the OP_Eq and similar

opcodes so that it avoids a lot of useless work.

FossilOrigin-Name: 4221f41af9df90da4183d45d0edfae19b4f7095ec35a203c8dfd2712799e3839
This commit is contained in:
drh 2021-05-17 16:54:52 +00:00
parent be12083bc7
commit 8546497383
3 changed files with 36 additions and 18 deletions

View File

@ -1,5 +1,5 @@
C Fix\sproblems\swith\srefering\sto\sCTEs\sfrom\swithin\ssub-selects\sin\sPARTITION\sBY\sor\sORDER\sBY\sclauses\sof\swindow\sframe\sdefinitions.\sAlso\sa\sproblem\swith\srenaming\sa\scolumn\swhen\sthe\sschema\scontains\sa\strigger\scontaining\sa\scorrelated\ssub-select\swithin\sa\swindow\sframes\sPARTITION\sBY\sor\sORDER\sBY\sclause.
D 2021-05-17T16:20:41.216
C Enhance\sthe\sinteger-comparison\soptimization\son\sthe\sOP_Eq\sand\ssimilar\nopcodes\sso\sthat\sit\savoids\sa\slot\sof\suseless\swork.
D 2021-05-17T16:54:52.605
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -615,7 +615,7 @@ F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048
F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286
F src/vdbe.c b26c70a380b0dbaa121ab91245d8a6369b6777ccfd92145bfaa6a15b15fd93b7
F src/vdbe.c d84dd30f6918ef9b3dcb16c2a5d3183632776634efe2bc7040875ea68ee5932e
F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
F src/vdbeInt.h 58980223a32495ad059d10581b83e133abdc77248b1bab85c080cab8a13bd819
F src/vdbeapi.c d9e99daf59fec928986838b3389a7337e82fec6b3b5de30206cb99fb4661b94e
@ -1913,7 +1913,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 391c73132c80df944fb49a17d8fe78203c54ac48f968ee9dd9dd8c769c0b4b10
R 1a3c07521ec89dbf97d54d6a90575f54
U dan
Z 75dc52bd6cfb538aa08788239a9d470b
P 4c6cd54a8db78e5535912e76856bed4f797261aaca4248c69d2e2452194de297
R 73d09b7d916ce62909b488068f093069
U drh
Z 794872f0c0978da2cc0d2cc549058a5f

View File

@ -1 +1 @@
4c6cd54a8db78e5535912e76856bed4f797261aaca4248c69d2e2452194de297
4221f41af9df90da4183d45d0edfae19b4f7095ec35a203c8dfd2712799e3839

View File

@ -2044,6 +2044,31 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
pIn3 = &aMem[pOp->p3];
flags1 = pIn1->flags;
flags3 = pIn3->flags;
if( (flags1 & flags3 & MEM_Int)!=0 ){
assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT );
/* Common case of comparison of two integers */
if( pIn3->u.i > pIn1->u.i ){
iCompare = +1;
if( sqlite3aGTb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
}else if( pIn3->u.i < pIn1->u.i ){
iCompare = -1;
if( sqlite3aLTb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
}else{
iCompare = 0;
if( sqlite3aEQb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
}
VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
break;
}
if( (flags1 | flags3)&MEM_Null ){
/* One or both operands are NULL */
if( pOp->p5 & SQLITE_NULLEQ ){
@ -2074,7 +2099,8 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
break;
}
}else{
/* Neither operand is NULL. Do a comparison. */
/* Neither operand is NULL and we couldn't do the special high-speed
** integer comparison case. So do a general-case comparison. */
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
if( (flags1 | flags3)&MEM_Str ){
@ -2087,14 +2113,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
applyNumericAffinity(pIn3,0);
}
}
/* Handle the common case of integer comparison here, as an
** optimization, to avoid a call to sqlite3MemCompare() */
if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){
if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; }
if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; }
res = 0;
goto compare_op;
}
}else if( affinity==SQLITE_AFF_TEXT ){
if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn1->flags & MEM_Int );
@ -2117,7 +2135,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
compare_op:
/* At this point, res is negative, zero, or positive if reg[P1] is
** less than, equal to, or greater than reg[P3], respectively. Compute
** the answer to this operator in res2, depending on what the comparison