Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Incremental code compaction in expr.c. Now about 4% smaller. Lots more work to do. (CVS 1183) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d292ba5148059dce3893b80eabdca4af |
User & Date: | drh 2004-01-16 15:55:38.000 |
Context
2004-01-16
| ||
16:42 | More compaction of expr.c. (CVS 1184) (check-in: 92e7f78057 user: drh tags: trunk) | |
15:55 | Incremental code compaction in expr.c. Now about 4% smaller. Lots more work to do. (CVS 1183) (check-in: d292ba5148 user: drh tags: trunk) | |
13:58 | Fix a buffer-overflow problem in the randStr function (used only for testing). (CVS 1182) (check-in: 42c79edc2e user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | < | | | > > > | < < | < < | | | | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.105 2004/01/16 15:55:38 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqliteMalloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ Expr *sqliteExpr(int op, Expr *pLeft, Expr *pRight, Token *pToken){ Expr *pNew; pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ /* When malloc fails, we leak memory from pLeft and pRight */ return 0; } pNew->op = op; pNew->pLeft = pLeft; pNew->pRight = pRight; if( pToken ){ assert( pToken->dyn==0 ); pNew->token = *pToken; pNew->span = *pToken; }else{ assert( pNew->token.dyn==0 ); assert( pNew->token.z==0 ); assert( pNew->token.n==0 ); if( pLeft && pRight ){ sqliteExprSpan(pNew, &pLeft->span, &pRight->span); }else{ pNew->span = pNew->token; } } return pNew; } /* ** Set the Expr.span field of the given expression to span all ** text between the two given tokens. */ void sqliteExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){ assert( pRight!=0 ); assert( pLeft!=0 ); /* Note: pExpr might be NULL due to a prior malloc failure */ if( pExpr && pRight->z && pLeft->z ){ if( pLeft->dyn==0 && pRight->dyn==0 ){ pExpr->span.z = pLeft->z; pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z); }else{ pExpr->span.z = 0; } } } /* ** Construct a new expression node for a function with multiple ** arguments. */ Expr *sqliteExprFunction(ExprList *pList, Token *pToken){ Expr *pNew; pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ /* sqliteExprListDelete(pList); // Leak pList when malloc fails */ return 0; } pNew->op = TK_FUNCTION; pNew->pList = pList; if( pToken ){ assert( pToken->dyn==0 ); pNew->token = *pToken; }else{ pNew->token.z = 0; } pNew->span = pNew->token; return pNew; } /* ** Recursively delete an expression tree. */ void sqliteExprDelete(Expr *p){ if( p==0 ) return; if( p->span.dyn ) sqliteFree((char*)p->span.z); if( p->token.dyn ) sqliteFree((char*)p->token.z); sqliteExprDelete(p->pLeft); sqliteExprDelete(p->pRight); sqliteExprListDelete(p->pList); sqliteSelectDelete(p->pSelect); sqliteFree(p); } /* ** The following group of routines make deep copies of expressions, ** expression lists, ID lists, and select statements. The copies can |
︙ | ︙ | |||
125 126 127 128 129 130 131 | pNew = sqliteMallocRaw( sizeof(*p) ); if( pNew==0 ) return 0; memcpy(pNew, p, sizeof(*pNew)); if( p->token.z!=0 ){ pNew->token.z = sqliteStrDup(p->token.z); pNew->token.dyn = 1; }else{ | | < < < < < < | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | pNew = sqliteMallocRaw( sizeof(*p) ); if( pNew==0 ) return 0; memcpy(pNew, p, sizeof(*pNew)); if( p->token.z!=0 ){ pNew->token.z = sqliteStrDup(p->token.z); pNew->token.dyn = 1; }else{ assert( pNew->token.z==0 ); } pNew->span.z = 0; pNew->pLeft = sqliteExprDup(p->pLeft); pNew->pRight = sqliteExprDup(p->pRight); pNew->pList = sqliteExprListDup(p->pList); pNew->pSelect = sqliteSelectDup(p->pSelect); return pNew; } void sqliteTokenCopy(Token *pTo, Token *pFrom){ if( pTo->dyn ) sqliteFree((char*)pTo->z); if( pFrom->z ){ pTo->n = pFrom->n; pTo->z = sqliteStrNDup(pFrom->z, pFrom->n); pTo->dyn = 1; }else{ pTo->z = 0; } } ExprList *sqliteExprListDup(ExprList *p){ ExprList *pNew; int i; if( p==0 ) return 0; pNew = sqliteMalloc( sizeof(*pNew) ); |
︙ | ︙ | |||
183 184 185 186 187 188 189 | } SrcList *sqliteSrcListDup(SrcList *p){ SrcList *pNew; int i; int nByte; if( p==0 ) return 0; nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); | | > > | | | | | | | | | | | > > | | | | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | } SrcList *sqliteSrcListDup(SrcList *p){ SrcList *pNew; int i; int nByte; if( p==0 ) return 0; nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); pNew = sqliteMallocRaw( nByte ); if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; i<p->nSrc; i++){ struct SrcList_item *pNewItem = &pNew->a[i]; struct SrcList_item *pOldItem = &p->a[i]; pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase); pNewItem->zName = sqliteStrDup(pOldItem->zName); pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; pNewItem->pTab = 0; pNewItem->pSelect = sqliteSelectDup(pOldItem->pSelect); pNewItem->pOn = sqliteExprDup(pOldItem->pOn); pNewItem->pUsing = sqliteIdListDup(pOldItem->pUsing); } return pNew; } IdList *sqliteIdListDup(IdList *p){ IdList *pNew; int i; if( p==0 ) return 0; pNew = sqliteMallocRaw( sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nId = pNew->nAlloc = p->nId; pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ) return 0; for(i=0; i<p->nId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; struct IdList_item *pOldItem = &p->a[i]; pNewItem->zName = sqliteStrDup(pOldItem->zName); pNewItem->idx = pOldItem->idx; } return pNew; } Select *sqliteSelectDup(Select *p){ Select *pNew; if( p==0 ) return 0; pNew = sqliteMallocRaw( sizeof(*p) ); if( pNew==0 ) return 0; pNew->isDistinct = p->isDistinct; pNew->pEList = sqliteExprListDup(p->pEList); pNew->pSrc = sqliteSrcListDup(p->pSrc); pNew->pWhere = sqliteExprDup(p->pWhere); pNew->pGroupBy = sqliteExprListDup(p->pGroupBy); pNew->pHaving = sqliteExprDup(p->pHaving); |
︙ | ︙ | |||
246 247 248 249 250 251 252 | ** initially NULL, then create a new expression list. */ ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){ int i; if( pList==0 ){ pList = sqliteMalloc( sizeof(ExprList) ); if( pList==0 ){ | | | < | | | > < > | | | | | | | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | ** initially NULL, then create a new expression list. */ ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){ int i; if( pList==0 ){ pList = sqliteMalloc( sizeof(ExprList) ); if( pList==0 ){ /* sqliteExprDelete(pExpr); // Leak memory if malloc fails */ return 0; } assert( pList->nAlloc==0 ); } if( pList->nAlloc<=pList->nExpr ){ pList->nAlloc = pList->nAlloc*2 + 4; pList->a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0])); if( pList->a==0 ){ /* sqliteExprDelete(pExpr); // Leak memory if malloc fails */ pList->nExpr = pList->nAlloc = 0; return pList; } } assert( pList->a!=0 ); if( pExpr || pName ){ struct ExprList_item *pItem = &pList->a[pList->nExpr++]; memset(pItem, 0, sizeof(*pItem)); pItem->pExpr = pExpr; if( pName ){ sqliteSetNString(&pItem->zName, pName->z, pName->n, 0); sqliteDequote(pItem->zName); } } return pList; } /* ** Delete an entire expression list. |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.209 2004/01/16 15:55:38 drh Exp $ */ #include "config.h" #include "sqlite.h" #include "hash.h" #include "vdbe.h" #include "parse.h" #include "btree.h" |
︙ | ︙ | |||
583 584 585 586 587 588 589 590 591 592 593 594 595 596 | u8 iDb; /* Index in sqlite.aDb[] of where this index is stored */ Index *pNext; /* The next index associated with the same table */ }; /* ** Each token coming out of the lexer is an instance of ** this structure. Tokens are also used as part of an expression. */ struct Token { const char *z; /* Text of the token. Not NULL-terminated! */ unsigned dyn : 1; /* True for malloced memory, false for static */ unsigned n : 31; /* Number of characters in this token */ }; | > > > > | 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | u8 iDb; /* Index in sqlite.aDb[] of where this index is stored */ Index *pNext; /* The next index associated with the same table */ }; /* ** Each token coming out of the lexer is an instance of ** this structure. Tokens are also used as part of an expression. ** ** Note if Token.z==0 then Token.dyn and Token.n are undefined and ** may contain random values. Do not make any assuptions about Token.dyn ** and Token.n when Token.z==0. */ struct Token { const char *z; /* Text of the token. Not NULL-terminated! */ unsigned dyn : 1; /* True for malloced memory, false for static */ unsigned n : 31; /* Number of characters in this token */ }; |
︙ | ︙ |