Add the EP_Leaf flag bit to the Expr.flags field to indicate Expr

nodes that do not have substructure.  Use that bit to avoid unnecessary
recursion.

FossilOrigin-Name: 8a6ea455cd1bf42ae0a7f1f1789baf88d782db13
This commit is contained in:
drh 2016-09-23 21:36:24 +00:00
parent e1c03b6233
commit 209bc522b0
7 changed files with 29 additions and 18 deletions

View File

@ -1,5 +1,5 @@
C Use\ssqlite3ExprAlloc()\sinstead\sof\ssqlite3PExpr()\sfor\sleaf\snodes\sin\sthe\nexpression\stree,\swhere\sappropriate.\s\sThis\sis\sboth\ssmaller\sand\sfaster.
D 2016-09-23T20:59:31.640
C Add\sthe\sEP_Leaf\sflag\sbit\sto\sthe\sExpr.flags\sfield\sto\sindicate\sExpr\nnodes\sthat\sdo\snot\shave\ssubstructure.\s\sUse\sthat\sbit\sto\savoid\sunnecessary\nrecursion.
D 2016-09-23T21:36:24.016
F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f
@ -324,7 +324,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 299117695b1f21ac62dfc5b608588810ba22ed0d
F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68
F src/attach.c 3e78d38abb5a4e3e0048a16ab662e6ffa323687c
F src/attach.c 8c19066b4b5357b5d66154e856c61df01e71203a
F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
F src/backup.c 92c2e3b5fcb47626413717138617f4d32f08aea4
F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
@ -339,7 +339,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7
F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec
F src/expr.c 13bc043a6a6cfde48a7d551242e721af79f7837d
F src/expr.c a27090ab1d9d9901c64974c43588a38a486d6a55
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80
F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771
@ -375,7 +375,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c bf5b71bde3e9b6110e7d6990607db881f6a471a2
F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d
F src/parse.y 2e0ac10d159ae28378d760e1284672dc83c12e59
F src/parse.y 028b531b442f06fd6f0177f6197f3384c7e6e538
F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812
@ -391,7 +391,7 @@ F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2
F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
F src/sqliteInt.h e7c39dc148cd38b947cbdd482986afba3fe9ef22
F src/sqliteInt.h 1137559f2e6f4e55d26ec83ce94ef57aa3748c8f
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
@ -466,7 +466,7 @@ F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a
F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2
F src/walker.c 83042807db1a27175fcb39be8f3e2a839dbdddb2
F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0
F src/where.c 5f91be9fe122e847c4e72d54d3989eb32a927981
F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613
F src/wherecode.c e412e09abad1eea213d85594cf46db9f877db56d
@ -1525,7 +1525,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 9a5a489d0d344274d0fc9fb9303503a454f42844
R 4f7e383818869f5430685b55e782c0cb
P afac0709cec577a7851e3711730712cf12eeb6af
R 1f3656e4b134bb6d596c11b8715739cb
U drh
Z 80e3136d01cf534e1ff43bad67f7dd75
Z aee870d3bef9f3e934093d2e8b8d0981

View File

@ -1 +1 @@
afac0709cec577a7851e3711730712cf12eeb6af
8a6ea455cd1bf42ae0a7f1f1789baf88d782db13

View File

@ -530,7 +530,7 @@ int sqlite3FixExpr(
return 1;
}
}
if( ExprHasProperty(pExpr, EP_TokenOnly) ) break;
if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
}else{

View File

@ -1016,18 +1016,25 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p!=0 );
/* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
if( !ExprHasProperty(p, EP_TokenOnly) ){
#ifdef SQLITE_DEBUG
if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
assert( p->pLeft==0 );
assert( p->pRight==0 );
assert( p->x.pSelect==0 );
}
#endif
if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
/* The Expr.x union is never used at the same time as Expr.pRight */
assert( p->x.pList==0 || p->pRight==0 );
if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
sqlite3ExprDelete(db, p->pRight);
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect);
}else{
sqlite3ExprListDelete(db, p->x.pList);
}
}
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( !ExprHasProperty(p, EP_Static) ){
sqlite3DbFree(db, p);
}
@ -1204,7 +1211,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
memcpy(zToken, p->u.zToken, nToken);
}
if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
@ -1216,7 +1223,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
/* Fill in pNew->pLeft and pNew->pRight. */
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, dupFlags);
if( ExprHasProperty(pNew, EP_Reduced) ){
if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
pNew->pLeft = p->pLeft ?
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
pNew->pRight = p->pRight ?
@ -1226,7 +1233,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
*pzBuffer = zAlloc;
}
}else{
if( !ExprHasProperty(p, EP_TokenOnly) ){
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
if( pNew->op==TK_SELECT_COLUMN ){
pNew->pLeft = p->pLeft;
}else{

View File

@ -854,6 +854,7 @@ idlist(A) ::= nm(Y).
pOut->pExpr = sqlite3ExprAlloc(pParse->db, op, &t, 1);
pOut->zStart = t.z;
pOut->zEnd = &t.z[t.n];
if( pOut->pExpr ) pOut->pExpr->flags |= EP_Leaf;
}
}

View File

@ -2338,6 +2338,7 @@ struct Expr {
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
#define EP_Alias 0x400000 /* Is an alias for a result set column */
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
/*
** Combinations of two or more EP_* flags

View File

@ -41,7 +41,9 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc || ExprHasProperty(pExpr,EP_TokenOnly) ) return rc & WRC_Abort;
if( rc || ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
return rc & WRC_Abort;
}
if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
if( pExpr->pRight && walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){