Add new routines to simplify dealing with collating sequences in expressions:

sqlite3ExprNNCollSeq() and sqlite3ExprCollSeqMatch().

FossilOrigin-Name: 490e488ea963fe725b16212822c8608f2b6abce688931b611446bc2cbfe6b87c
This commit is contained in:
drh 2017-09-28 01:58:23 +00:00
parent db8e68b4cd
commit 70efa84da7
7 changed files with 55 additions and 35 deletions

View File

@ -1,5 +1,5 @@
C Indexes\son\sexpressions\swith\sa\sCOLLATE\sclause\sare\sable\sto\ssatisfy\san\sORDER\sBY\s\nwith\sthe\ssame\sCOLLATE\sclause.
D 2017-09-28T01:09:42.223
C Add\snew\sroutines\sto\ssimplify\sdealing\swith\scollating\ssequences\sin\sexpressions:\nsqlite3ExprNNCollSeq()\sand\ssqlite3ExprCollSeqMatch().
D 2017-09-28T01:58:23.335
F Makefile.in 4bc36d913c2e3e2d326d588d72f618ac9788b2fd4b7efda61102611a6495c3ff
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 6033b51b6aea702ea059f6ab2d47b1d3cef648695f787247dd4fb395fe60673f
@ -411,7 +411,7 @@ F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0
F src/date.c 48f743d88bbe88f848532d333cca84f26e52a4f217e86f86be7fc1b919c33d74
F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720
F src/delete.c 21a5f1812fdb599e9f7afb9f650bdabab60a3afd51d7e94e539c982f647b0023
F src/expr.c 82fedd57c8ce9e7dc16a003ad4cd863308787d5b5cbd0f83263b37805a56319c
F src/expr.c 628395aea8bbf4e2851565f9dab76565e3100ca0836a337fb748834c9cec9f04
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333
F src/func.c b4d259af627e3cd9510cf08db37f0bcc88b1887c735169c74490c3739d5cf5c6
@ -458,13 +458,13 @@ F src/printf.c 40aee47ae9be4bd3dbdc8968bd07fddc027be8edec8daddf24d3391d36698a1c
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 9fa0db382f43217e207a145b8c6cec26e85cd1a42a8428ee8b3df5870dfea0f4
F src/select.c 843ac757ad04480845ce4c2d2f742c13c8f751dec115a9a7d3dbef33c9264598
F src/shell.c c1206a23d9239f8f51751d3be9b8c3b02fa4103546bea1add7f864d84a8276ab
F src/shell.c.in bb9720a8c5c98d3984b16ab7540e7142bcae959666ecf248bfc523a1d44220ee
F src/sqlite.h.in ab4f8a29d1580dfaeb6891fa1b83cff8229ba0daa56994707ceaca71495d9ab7
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47
F src/sqliteInt.h 12aa1f626b3209ffa6a50d9d1e6b4235abd33273a0fcbfeedb66f573a68932b9
F src/sqliteInt.h 954fed875c59d283870f13010bbbb96d8b25cf3db0683843403c36e9dfcf1bdd
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@ -540,10 +540,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 839db09792fead5052bb35e533fa485e134913d547d05b5f42e537b73e63f07a
F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
F src/walker.c 3ccfa8637f95355bff61144e01a615b8ef26f79c312880848da73f03367da1e6
F src/where.c 5b004ea313a0250ed94d064b7795831ca72b53f956e6b776b5102ebe8e43532e
F src/where.c 049522adcf5426f1a8c3ed07be15e1ffa3266afd34e8e7bee64b63e2fbfad0b5
F src/whereInt.h 82c04c5075308abbac59180c8bad5ecb45b07453981f60a53f3c7dee21e1e971
F src/wherecode.c e8c2ece5843ea56e6c90277d421f2d628f3f7b7c976642369cc519f008e1d2b1
F src/whereexpr.c 4953ca4e769c047d0a00a1ba9085849626b1f3a6e89f6befcf5c38fa0722acdd
F src/whereexpr.c afcac9cccfc0fdaccbdda94034a398947b6dc47dbf821c1b496261722832a6a4
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@ -1655,7 +1655,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 80277d2fc9b76fe41e345d00952da1528e69884f25911cf6e4f78b09ff778421
R c774dcc4924296b1d5d3f0941d695b78
P 0413001843dce7c63659d39b329ca14cdcd54f4407922f51b2fb7659572a733e
R 0aa0c6a22a3ca8a1377c9aa1ffa8dd82
U drh
Z 3745bfdcfe1c333d46cc8a31ac4a80d4
Z 1f5f89ecf882e16436178057d38d6ed8

View File

@ -1 +1 @@
0413001843dce7c63659d39b329ca14cdcd54f4407922f51b2fb7659572a733e
490e488ea963fe725b16212822c8608f2b6abce688931b611446bc2cbfe6b87c

View File

@ -124,6 +124,11 @@ Expr *sqlite3ExprSkipCollate(Expr *pExpr){
** Return the collation sequence for the expression pExpr. If
** there is no defined collating sequence, return NULL.
**
** See also: sqlite3ExprNNCollSeq()
**
** The sqlite3ExprNNCollSeq() works the same exact that it returns the
** default collation if pExpr has no defined collation.
**
** The collating sequence might be determined by a COLLATE operator
** or by the presence of a column with a defined collating sequence.
** COLLATE operators take first precedence. Left operands take
@ -188,6 +193,32 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
return pColl;
}
/*
** Return the collation sequence for the expression pExpr. If
** there is no defined collating sequence, return a pointer to the
** defautl collation sequence.
**
** See also: sqlite3ExprCollSeq()
**
** The sqlite3ExprCollSeq() routine works the same except that it
** returns NULL if there is no defined collation.
*/
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
if( p==0 ) p = pParse->db->pDfltColl;
assert( p!=0 );
return p;
}
/*
** Return TRUE if the two expressions have equivalent collating sequences.
*/
int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
}
/*
** pExpr is an operand of a comparison operator. aff2 is the
** type affinity of the other operand. This routine returns the
@ -1843,8 +1874,8 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
for(i=0; i<pGroupBy->nExpr; i++){
Expr *p = pGroupBy->a[i].pExpr;
if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){
CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p);
if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){
CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p);
if( sqlite3_stricmp("BINARY", pColl->zName)==0 ){
return WRC_Prune;
}
}

View File

@ -1109,10 +1109,7 @@ static KeyInfo *keyInfoFromExprList(
if( pInfo ){
assert( sqlite3KeyInfoIsWriteable(pInfo) );
for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
CollSeq *pColl;
pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
if( !pColl ) pColl = db->pDfltColl;
pInfo->aColl[i-iStart] = pColl;
pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr);
pInfo->aSortOrder[i-iStart] = pItem->sortOrder;
}
}

View File

@ -4004,6 +4004,8 @@ int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
Expr *sqlite3ExprSkipCollate(Expr*);

View File

@ -403,8 +403,8 @@ static int findIndexCol(
&& p->iColumn==pIdx->aiColumn[iCol]
&& p->iTable==iBase
){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){
CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr);
if( 0==sqlite3StrICmp(pColl->zName, zColl) ){
return i;
}
}
@ -3579,14 +3579,10 @@ static i8 wherePathSatisfiesOrderBy(
if( j>=pLoop->nLTerm ) continue;
}
if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
const char *z1, *z2;
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
if( !pColl ) pColl = db->pDfltColl;
z1 = pColl->zName;
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
if( !pColl ) pColl = db->pDfltColl;
z2 = pColl->zName;
if( sqlite3StrICmp(z1, z2)!=0 ) continue;
if( sqlite3ExprCollSeqMatch(pWInfo->pParse,
pOrderBy->a[i].pExpr, pTerm->pExpr)==0 ){
continue;
}
testcase( pTerm->pExpr->op==TK_IS );
}
obSat |= MASKBIT(i);
@ -3696,8 +3692,7 @@ static i8 wherePathSatisfiesOrderBy(
}
}
if( iColumn!=XN_ROWID ){
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
if( !pColl ) pColl = db->pDfltColl;
pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
}
pLoop->u.btree.nIdxCol = j+1;

View File

@ -842,7 +842,6 @@ static void exprAnalyzeOrTerm(
static int termIsEquivalence(Parse *pParse, Expr *pExpr){
char aff1, aff2;
CollSeq *pColl;
const char *zColl1, *zColl2;
if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
@ -855,11 +854,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){
}
pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
zColl1 = pColl ? pColl->zName : 0;
pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
zColl2 = pColl ? pColl->zName : 0;
return sqlite3_stricmp(zColl1, zColl2)==0;
return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight);
}
/*