When we play games with COLLATE in order to commute an operator in the
WHERE clause processing, be sure not to use the commuted operator to qualify a partial index, as insufficient COLLATE information is preserved to verify that the expression will correctly qualify the index. Ticket [767a8cbc6d20bd68] FossilOrigin-Name: 5351e920f489562f959ab8a376ff720f845ea165e0cdc7c3a271aac53c2aa64a
This commit is contained in:
parent
4fc836546e
commit
c7d12f4ad4
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sa\sbug\sintroduced\searlier\stoday\sby\scheck-in\s[88833a9c2849c959].\nTicket\s[29f635e0af71234b]
|
||||
D 2019-09-02T22:13:06.403
|
||||
C When\swe\splay\sgames\swith\sCOLLATE\sin\sorder\sto\scommute\san\soperator\sin\sthe\nWHERE\sclause\sprocessing,\sbe\ssure\snot\sto\suse\sthe\scommuted\soperator\sto\squalify\na\spartial\sindex,\sas\sinsufficient\sCOLLATE\sinformation\sis\spreserved\sto\sverify\nthat\sthe\sexpression\swill\scorrectly\squalify\sthe\sindex.\nTicket\s[767a8cbc6d20bd68]
|
||||
D 2019-09-03T14:27:25.935
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -610,10 +610,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d
|
||||
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
|
||||
F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd
|
||||
F src/where.c fb546afbdbedc77a6193a236db92f6f85bc8e17412ec596230dd8aee03a93716
|
||||
F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217
|
||||
F src/where.c 9685d5988b79b93ebbe46941fbdb60d14861bb0fe3f9126117ef1753acc69b64
|
||||
F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9
|
||||
F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b
|
||||
F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f
|
||||
F src/whereexpr.c b3bbae199e7acd8d0fa822c9a29cbb822ef2b3d84d68de55a3d60b013f5d5da4
|
||||
F src/window.c 96b0c033d33408f16ac8b177eac6362ee53a23d9b6d7a51a04289ab2f956bb77
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test da465d3d490ab24ef64f7715b5953343a4967762b9350b29eb1462879ff3fb9e
|
||||
@ -1048,7 +1048,7 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
|
||||
F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
|
||||
F test/index6.test bae04b456a1845d8d48af751ac5b9bba5571551b96ef39d2b5b1db48cadd0fac
|
||||
F test/index6.test 4d1dd3cab97fba2ddf30bb70afc82eab35bd6e61788b3ac941e55263f81ef7e9
|
||||
F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b020
|
||||
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
|
||||
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
|
||||
@ -1839,7 +1839,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 9490683ae883561fa347cbe54ebdd61188d849b4852d904b508250ba5d0807ef
|
||||
R 931628c07078d6a1ec560a2e18a3f53f
|
||||
P 6e7b4527d32cc1be0294614b9d7363d4b59cf654a954b86515b3f6888975ce73
|
||||
R f93cc76f663e94933b1f2f65b53349fd
|
||||
U drh
|
||||
Z 31499ded87036041191e77b0df0459dc
|
||||
Z 391da90ad359183d92b0ba19729274a1
|
||||
|
@ -1 +1 @@
|
||||
6e7b4527d32cc1be0294614b9d7363d4b59cf654a954b86515b3f6888975ce73
|
||||
5351e920f489562f959ab8a376ff720f845ea165e0cdc7c3a271aac53c2aa64a
|
@ -2800,7 +2800,9 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
|
||||
}
|
||||
if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
|
||||
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
Expr *pExpr;
|
||||
if( pTerm->wtFlags & TERM_NOPARTIDX ) continue;
|
||||
pExpr = pTerm->pExpr;
|
||||
if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
|
||||
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
|
||||
){
|
||||
|
@ -291,6 +291,7 @@ struct WhereTerm {
|
||||
#define TERM_LIKE 0x400 /* The original LIKE operator */
|
||||
#define TERM_IS 0x800 /* Term.pExpr is an IS operator */
|
||||
#define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */
|
||||
#define TERM_NOPARTIDX 0x2000 /* Not for use to enable a partial index */
|
||||
|
||||
/*
|
||||
** An instance of the WhereScan object is used as an iterator for locating
|
||||
|
@ -117,10 +117,16 @@ static int allowedOp(int op){
|
||||
** the left hand side of a comparison overrides any collation sequence
|
||||
** attached to the right. For the same reason the EP_Collate flag
|
||||
** is not commuted.
|
||||
**
|
||||
** The return value is extra flags that are added to the WhereTerm object
|
||||
** after it is commuted. The only extra flag ever added is TERM_NOPARTIDX
|
||||
** which prevents the term from being used to enable a partial index if
|
||||
** COLLATE changes have been made.
|
||||
*/
|
||||
static void exprCommute(Parse *pParse, Expr *pExpr){
|
||||
static u16 exprCommute(Parse *pParse, Expr *pExpr){
|
||||
u16 expRight = (pExpr->pRight->flags & EP_Collate);
|
||||
u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
|
||||
u16 wtFlags = 0;
|
||||
assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
|
||||
if( expRight==expLeft ){
|
||||
/* Either X and Y both have COLLATE operator or neither do */
|
||||
@ -128,11 +134,13 @@ static void exprCommute(Parse *pParse, Expr *pExpr){
|
||||
/* Both X and Y have COLLATE operators. Make sure X is always
|
||||
** used by clearing the EP_Collate flag from Y. */
|
||||
pExpr->pRight->flags &= ~EP_Collate;
|
||||
wtFlags |= TERM_NOPARTIDX;
|
||||
}else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
|
||||
/* Neither X nor Y have COLLATE operators, but X has a non-default
|
||||
** collating sequence. So add the EP_Collate marker on X to cause
|
||||
** it to be searched first. */
|
||||
pExpr->pLeft->flags |= EP_Collate;
|
||||
wtFlags |= TERM_NOPARTIDX;
|
||||
}
|
||||
}
|
||||
SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
|
||||
@ -144,6 +152,7 @@ static void exprCommute(Parse *pParse, Expr *pExpr){
|
||||
assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
|
||||
pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
|
||||
}
|
||||
return wtFlags;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1140,7 +1149,7 @@ static void exprAnalyze(
|
||||
pDup = pExpr;
|
||||
pNew = pTerm;
|
||||
}
|
||||
exprCommute(pParse, pDup);
|
||||
pNew->wtFlags |= exprCommute(pParse, pDup);
|
||||
pNew->leftCursor = aiCurCol[0];
|
||||
pNew->u.leftColumn = aiCurCol[1];
|
||||
testcase( (prereqLeft | extraRight) != prereqLeft );
|
||||
|
@ -462,5 +462,23 @@ do_execsql_test index6-15.5 {
|
||||
SELECT 1 FROM t0 WHERE (c0 IS FALSE) IN (FALSE);
|
||||
} {1}
|
||||
|
||||
# 2019-09-03
|
||||
# Ticket https://sqlite.org/src/info/767a8cbc6d20bd68
|
||||
do_execsql_test index6-16.1 {
|
||||
DROP TABLE t0;
|
||||
CREATE TABLE t0(c0 COLLATE NOCASE, c1);
|
||||
CREATE INDEX i0 ON t0(0) WHERE c0 >= c1;
|
||||
INSERT INTO t0 VALUES('a', 'B');
|
||||
SELECT c1 <= c0, c0 >= c1 FROM t0;
|
||||
} {1 0}
|
||||
do_execsql_test index6-16.2 {
|
||||
SELECT 2 FROM t0 WHERE c0 >= c1;
|
||||
} {}
|
||||
do_execsql_test index6-16.3 {
|
||||
SELECT 3 FROM t0 WHERE c1 <= c0;
|
||||
} {3}
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
Loading…
x
Reference in New Issue
Block a user