/ Check-in [7324c7f2]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add tail recursion to the sqlite3ExprDelete() routine in order to keep down stack space usage for really, really large expressions. Later: The tail recursion is dangerous since the recursion might happen after the expression has been freed.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | mistake
Files: files | file ages | folders
SHA1: 7324c7f2f87af63729dfef2c9884c77ef9fa9d5d
User & Date: drh 2010-10-27 19:23:13
Original Comment: Add tail recursion to the sqlite3ExprDelete() routine in order to keep down stack space usage for really, really large expressions.
Context
2010-10-28
15:49
This was suppose to go on "trunk" but got committed to the wrong branch. Add new "dynamic_triggers" test case to threadtest3.c. Closed-Leaf check-in: d9e588ef user: dan tags: mistake
2010-10-27
19:23
Add tail recursion to the sqlite3ExprDelete() routine in order to keep down stack space usage for really, really large expressions. Later: The tail recursion is dangerous since the recursion might happen after the expression has been freed. check-in: 7324c7f2 user: drh tags: mistake
19:08
Avoid trying to allocate a negative number of bytes of memory in the test wrapper for sqlite3_blob_read(). check-in: 739b5d9a user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

606
607
608
609
610
611
612
613

614
615
616

617

618
619
620
621
622
623
624
625
626
627


628
629
630
631
632
633
634
  }
}

/*
** Recursively delete an expression tree.
*/
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
  if( p==0 ) return;

  if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
    sqlite3ExprDelete(db, p->pLeft);
    sqlite3ExprDelete(db, p->pRight);

    if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){

      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_Static) ){
    sqlite3DbFree(db, p);


  }
}

/*
** Return the number of bytes allocated for the expression structure 
** passed as the first argument. This is always one of EXPR_FULLSIZE,
** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.







|
>
|
|
|
>
|
>
|
|
|
|
|
|
|
|
|
|
>
>







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
  }
}

/*
** Recursively delete an expression tree.
*/
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
  while( p ){
    Expr *pNext = 0;
    if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
      pNext = p->pLeft;
      sqlite3ExprDelete(db, p->pRight);
      if( !ExprHasProperty(p, EP_Reduced)
       && (p->flags2 & EP2_MallocedToken)!=0
      ){
        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_Static) ){
      sqlite3DbFree(db, p);
    }
    p = pNext;
  }
}

/*
** Return the number of bytes allocated for the expression structure 
** passed as the first argument. This is always one of EXPR_FULLSIZE,
** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.