mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-05 04:30:38 +03:00
Improvements to the Expr comparison routine to make it more general.
Improvements to unary-minus code generation so that it can make use of a global constant register with a zero value. FossilOrigin-Name: 835be656bb0e83c8108104869166aa9dd850d265
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Simplify\sthe\srange\sscan\scode\sgenerate\swhile\salso\savoiding\san\sunnecessary\nOP_Affinity\sopcode.
|
C Improvements\sto\sthe\sExpr\scomparison\sroutine\sto\smake\sit\smore\sgeneral.\nImprovements\sto\sunary-minus\scode\sgeneration\sso\sthat\sit\scan\smake\suse\sof\na\sglobal\sconstant\sregister\swith\sa\szero\svalue.
|
||||||
D 2013-11-15T12:41:01.696
|
D 2013-11-15T15:52:39.123
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
|
F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
|||||||
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
|
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
|
||||||
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
|
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
|
||||||
F src/delete.c ddb92f44595366c4817e576b5f11cad5a915c3ef
|
F src/delete.c ddb92f44595366c4817e576b5f11cad5a915c3ef
|
||||||
F src/expr.c b54ac7b5a77cf2967b4194aba95005544e8b705e
|
F src/expr.c eb7eb7fa7848dc4e3b67a2f0bf32f794804ca38a
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6
|
F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6
|
||||||
F src/func.c 96caa9dfd1febf9a4b720de4c43ccfb392a52b73
|
F src/func.c 96caa9dfd1febf9a4b720de4c43ccfb392a52b73
|
||||||
@@ -224,7 +224,7 @@ F src/shell.c b98e74123d6c2e20369607c1da2d23c71db633d9
|
|||||||
F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d
|
F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d
|
||||||
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
||||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||||
F src/sqliteInt.h c5dfd52fcc677725c750b1570b090f70a5cb60ec
|
F src/sqliteInt.h 11b0dd04b1a2eb86a348fd818c7a63bf015cb0dd
|
||||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P cd579727b107a07140b94f5839d193959d29e6db
|
P 372686bfbb1da08b04bddb085e30da5dbc8b30d8
|
||||||
R 16d0a5bce69ca1eea8baa7da2e33f0a4
|
R a53a2df918863d2e307a62344ad87323
|
||||||
U drh
|
U drh
|
||||||
Z 29979dcda00f70bdf360a155d984f65d
|
Z a11accb78dd4b773c18bb01c1b2ffc18
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
372686bfbb1da08b04bddb085e30da5dbc8b30d8
|
835be656bb0e83c8108104869166aa9dd850d265
|
||||||
47
src/expr.c
47
src/expr.c
@@ -2356,6 +2356,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
int regFree2 = 0; /* If non-zero free this temporary register */
|
int regFree2 = 0; /* If non-zero free this temporary register */
|
||||||
int r1, r2, r3, r4; /* Various register numbers */
|
int r1, r2, r3, r4; /* Various register numbers */
|
||||||
sqlite3 *db = pParse->db; /* The database connection */
|
sqlite3 *db = pParse->db; /* The database connection */
|
||||||
|
Expr tempX; /* Temporary expression node */
|
||||||
|
|
||||||
assert( target>0 && target<=pParse->nMem );
|
assert( target>0 && target<=pParse->nMem );
|
||||||
if( v==0 ){
|
if( v==0 ){
|
||||||
@@ -2575,8 +2576,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
codeReal(v, pLeft->u.zToken, 1, target);
|
codeReal(v, pLeft->u.zToken, 1, target);
|
||||||
#endif
|
#endif
|
||||||
}else{
|
}else{
|
||||||
regFree1 = r1 = sqlite3GetTempReg(pParse);
|
tempX.op = TK_INTEGER;
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, r1);
|
tempX.flags = EP_IntValue|EP_TokenOnly;
|
||||||
|
tempX.u.iValue = 0;
|
||||||
|
r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1);
|
||||||
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2);
|
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2);
|
||||||
sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
|
sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
|
||||||
testcase( regFree2==0 );
|
testcase( regFree2==0 );
|
||||||
@@ -2892,7 +2895,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
ExprList *pEList; /* List of WHEN terms */
|
ExprList *pEList; /* List of WHEN terms */
|
||||||
struct ExprList_item *aListelem; /* Array of WHEN terms */
|
struct ExprList_item *aListelem; /* Array of WHEN terms */
|
||||||
Expr opCompare; /* The X==Ei expression */
|
Expr opCompare; /* The X==Ei expression */
|
||||||
Expr cacheX; /* Cached expression X */
|
|
||||||
Expr *pX; /* The X expression */
|
Expr *pX; /* The X expression */
|
||||||
Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
|
Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
|
||||||
VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
|
VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
|
||||||
@@ -2904,13 +2906,13 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
nExpr = pEList->nExpr;
|
nExpr = pEList->nExpr;
|
||||||
endLabel = sqlite3VdbeMakeLabel(v);
|
endLabel = sqlite3VdbeMakeLabel(v);
|
||||||
if( (pX = pExpr->pLeft)!=0 ){
|
if( (pX = pExpr->pLeft)!=0 ){
|
||||||
cacheX = *pX;
|
tempX = *pX;
|
||||||
testcase( pX->op==TK_COLUMN );
|
testcase( pX->op==TK_COLUMN );
|
||||||
testcase( pX->op==TK_REGISTER );
|
testcase( pX->op==TK_REGISTER );
|
||||||
exprToRegister(&cacheX, sqlite3ExprCodeTemp(pParse, pX, ®Free1));
|
exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, ®Free1));
|
||||||
testcase( regFree1==0 );
|
testcase( regFree1==0 );
|
||||||
opCompare.op = TK_EQ;
|
opCompare.op = TK_EQ;
|
||||||
opCompare.pLeft = &cacheX;
|
opCompare.pLeft = &tempX;
|
||||||
pTest = &opCompare;
|
pTest = &opCompare;
|
||||||
/* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
|
/* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
|
||||||
** The value in regFree1 might get SCopy-ed into the file result.
|
** The value in regFree1 might get SCopy-ed into the file result.
|
||||||
@@ -3732,16 +3734,18 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
** an incorrect 0 or 1 could lead to a malfunction.
|
** an incorrect 0 or 1 could lead to a malfunction.
|
||||||
*/
|
*/
|
||||||
int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
|
int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
|
||||||
if( pA==0||pB==0 ){
|
u32 combinedFlags;
|
||||||
|
if( pA==0 || pB==0 ){
|
||||||
return pB==pA ? 0 : 2;
|
return pB==pA ? 0 : 2;
|
||||||
}
|
}
|
||||||
assert( !ExprHasProperty(pA, EP_TokenOnly|EP_Reduced) );
|
combinedFlags = pA->flags | pB->flags;
|
||||||
assert( !ExprHasProperty(pB, EP_TokenOnly|EP_Reduced) );
|
if( combinedFlags & EP_IntValue ){
|
||||||
if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
|
if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
|
if( pA->op!=pB->op /*&& (pA->op!=TK_REGISTER || pA->op2!=pB->op)*/ ){
|
||||||
if( pA->op!=pB->op && (pA->op!=TK_REGISTER || pA->op2!=pB->op) ){
|
|
||||||
if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
|
if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -3750,21 +3754,24 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
|
|||||||
}
|
}
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken ){
|
||||||
|
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
|
||||||
|
return pA->op==TK_COLLATE ? 1 : 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
|
||||||
|
testcase( combinedFlags & EP_TokenOnly );
|
||||||
|
testcase( combinedFlags & EP_Reduced );
|
||||||
|
if( (combinedFlags & EP_TokenOnly)==0 ){
|
||||||
|
if( combinedFlags & EP_xIsSelect ) return 2;
|
||||||
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
|
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
|
||||||
if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
|
if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
|
||||||
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
|
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
|
||||||
|
if( (combinedFlags & EP_Reduced)==0 ){
|
||||||
if( pA->iColumn!=pB->iColumn ) return 2;
|
if( pA->iColumn!=pB->iColumn ) return 2;
|
||||||
if( pA->iTable!=pB->iTable
|
if( pA->iTable!=pB->iTable
|
||||||
&& pA->op!=TK_REGISTER
|
&& pA->op!=TK_REGISTER
|
||||||
&& (pA->iTable!=iTab || pB->iTable>=0) ) return 2;
|
&& (pA->iTable!=iTab || pB->iTable>=0) ) return 2;
|
||||||
if( ExprHasProperty(pA, EP_IntValue) ){
|
|
||||||
if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
|
|
||||||
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
|
|
||||||
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
|
|
||||||
return pA->op==TK_COLLATE ? 1 : 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1829,7 +1829,7 @@ struct Expr {
|
|||||||
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
|
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
|
||||||
#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
|
#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
|
||||||
#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE opeartor */
|
#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE opeartor */
|
||||||
#define EP_FixedDest 0x000200 /* Result needed in a specific register */
|
/* unused 0x000200 */
|
||||||
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
|
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
|
||||||
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
|
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
|
||||||
#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */
|
#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */
|
||||||
|
|||||||
Reference in New Issue
Block a user