]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the EP_Leaf flag bit to the Expr.flags field to indicate Expr
authordrh <drh@noemail.net>
Fri, 23 Sep 2016 21:36:24 +0000 (21:36 +0000)
committerdrh <drh@noemail.net>
Fri, 23 Sep 2016 21:36:24 +0000 (21:36 +0000)
nodes that do not have substructure.  Use that bit to avoid unnecessary
recursion.

FossilOrigin-Name: 8a6ea455cd1bf42ae0a7f1f1789baf88d782db13

manifest
manifest.uuid
src/attach.c
src/expr.c
src/parse.y
src/sqliteInt.h
src/walker.c

index 17b20f9f71d4af8545bd86e3cec5ff7a8ac8f797..143d93ba317725976ab1781e85516a76153fc5ae 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index 1c3ed882bc7fd5298b9c1c2cbedcacbbd423f130..2923794dec1eddf7867e83a761b03be58fa443e7 100644 (file)
@@ -1 +1 @@
-afac0709cec577a7851e3711730712cf12eeb6af
\ No newline at end of file
+8a6ea455cd1bf42ae0a7f1f1789baf88d782db13
\ No newline at end of file
index a9fdc3676149d730044affbe66b6785ff6e96610..507b9c1238099b88f61b678373d86937d2cfa167 100644 (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{
index ee2ad2f59d6dd1c35e7129780796af14a4708a1a..e8c245ec4d917d108596f08bc7d2b53054872d5a 100644 (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{
index f15f2f59a7e367d4d6a8814abf2b3f5ff507df3c..19d28c4e654a2deb6f9627098d29a39db54609ec 100644 (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;
   }
 }
 
index 6d736b47a6945a83aab1112d67af5cf6eca34b5b..cba894db0532475ed92db76fc85aa1fcb079f684 100644 (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
index 5abc3b9add23f4aa3a775084e412db4dec3f724c..d1b1e96a2d1eb7908ad32673bf7880cde4bb2fad 100644 (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) ){