Add new routines to simplify dealing with collating sequences in expressions:
sqlite3ExprNNCollSeq() and sqlite3ExprCollSeqMatch(). FossilOrigin-Name: 490e488ea963fe725b16212822c8608f2b6abce688931b611446bc2cbfe6b87c
This commit is contained in:
parent
db8e68b4cd
commit
70efa84da7
20
manifest
20
manifest
@ -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
|
||||
|
@ -1 +1 @@
|
||||
0413001843dce7c63659d39b329ca14cdcd54f4407922f51b2fb7659572a733e
|
||||
490e488ea963fe725b16212822c8608f2b6abce688931b611446bc2cbfe6b87c
|
35
src/expr.c
35
src/expr.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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*);
|
||||
|
19
src/where.c
19
src/where.c
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user