From b7ca2177d7ddcf5dbf06d1b210fa92750324249b Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Aug 2016 17:54:46 +0000 Subject: [PATCH] Fix a problem with affinity changes and vector range comparisons. FossilOrigin-Name: b34413ac7e34369b4420e57b0132249dca68a7b0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 50 +++++++++++++++++++++++++++++++++---------------- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 1bca06079a..cb2c5f28b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sROWID\svalues\sin\sindexed\svector\scomparisons. -D 2016-08-26T13:19:49.916 +C Fix\sa\sproblem\swith\saffinity\schanges\sand\svector\srange\scomparisons. +D 2016-08-26T17:54:46.350 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c bad93f9bc5e62c38d2e0d2f572dd01d359c8d4cb F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 5a5528c39be09593cada6ae465d7a0f48db0077f +F src/wherecode.c 71de4d2d36fa3afe6160e98334f1a717c226ee86 F src/whereexpr.c 7f9ada866d48d15d09754ae819c1c40efe3b2aff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1521,7 +1521,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 397617009e07004596476d6f5644fdf84c376f54 -R bebe23f740f385ed54a0790b48a77a67 -U drh -Z b30339a1eb9e7f2b74488db2fab0ab4b +P b0cc6be4eb81f21b11796e1f14d4412bf21dea6e +R 0bd9bba299be3b1c19235baf0c5a546b +U dan +Z 7b1a4a5a11db26063e955544de8c89fc diff --git a/manifest.uuid b/manifest.uuid index f2f928f54a..ab39b9341f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0cc6be4eb81f21b11796e1f14d4412bf21dea6e \ No newline at end of file +b34413ac7e34369b4420e57b0132249dca68a7b0 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 65079872e1..34894fe1bb 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -350,6 +350,32 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ } } +/* +** Expression pRight, which is the RHS of a comparison operation, is +** either a vector of n elements or, if n==1, a scalar expression. +** Before the comparison operation, affinity zAff is to be applied +** to the pRight values. This function modifies characters within the +** affinity string to SQLITE_AFF_BLOB if either: +** +** * the comparison will be performed with no affinity, or +** * the affinity change in zAff is guaranteed not to change the value. +*/ +static void updateRangeAffinityStr( + Parse *pParse, /* Parse context */ + Expr *pRight, /* RHS of comparison */ + int n, /* Number of vector elements in comparison */ + char *zAff /* Affinity string to modify */ +){ + int i; + for(i=0; i=nEq ); - if( zStartAff ) cEndAff = zStartAff[nEq]; + if( zStartAff && nTop ){ + zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]); + } addrNxt = pLevel->addrNxt; testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); @@ -1441,15 +1469,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverage(v); } if( zStartAff ){ - if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_BLOB){ - /* Since the comparison is to be performed with no conversions - ** applied to the operands, set the affinity to apply to pRight to - ** SQLITE_AFF_BLOB. */ - zStartAff[nEq] = SQLITE_AFF_BLOB; - } - if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){ - zStartAff[nEq] = SQLITE_AFF_BLOB; - } + updateRangeAffinityStr(pParse, pRight, nBtm, &zStartAff[nEq]); } nConstraint += nBtm; testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); @@ -1498,11 +1518,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); VdbeCoverage(v); } - if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_BLOB - && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff) - ){ - codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff); - } + updateRangeAffinityStr(pParse, pRight, nTop, zEndAff); + codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff); nConstraint += nTop; testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); @@ -1517,6 +1534,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( nConstraint++; } sqlite3DbFree(db, zStartAff); + sqlite3DbFree(db, zEndAff); /* Top of the loop body */ pLevel->p2 = sqlite3VdbeCurrentAddr(v);