Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix some memory leaks that can occur if a memory allocation fails. (CVS 2388) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9a358fc33d726d0b5782bf65b50f61f2 |
User & Date: | danielk1977 2005-03-16 12:15:21.000 |
Context
2005-03-17
| ||
03:15 | Fix a bug in the calculation of the table record header size. Ticket #1163. (CVS 2389) (check-in: bf82a04ff7 user: drh tags: trunk) | |
2005-03-16
| ||
12:15 | Fix some memory leaks that can occur if a memory allocation fails. (CVS 2388) (check-in: 9a358fc33d user: danielk1977 tags: trunk) | |
2005-03-15
| ||
17:09 | When creating a new database, delete any preexisting journal that might be left over from a prior database with the same name. Ticket #1152. (CVS 2387) (check-in: 856e2ec968 user: drh tags: trunk) | |
Changes
Changes to src/attach.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** 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. ** ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** | | | > | 1 2 3 4 5 6 7 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 | /* ** 2003 April 6 ** ** 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. ** ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** ** $Id: attach.c,v 1.33 2005/03/16 12:15:21 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** This routine is called by the parser to process an ATTACH statement: ** ** ATTACH DATABASE filename AS dbname ** ** The pFilename and pDbname arguments are the tokens that define the ** filename and dbname in the ATTACH statement. */ void sqlite3Attach( Parse *pParse, /* The parser context */ Token *pFilename, /* Name of database file */ Token *pDbname, /* Name of the database to use internally */ int keyType, /* 0: no key. 1: TEXT, 2: BLOB */ Token *pKey /* Text of the key for keytype 1 and 2 */ ){ Db *aNew; int rc, i; char *zFile = 0; char *zName = 0; sqlite3 *db; Vdbe *v; v = sqlite3GetVdbe(pParse); if( !v ) return; sqlite3VdbeAddOp(v, OP_Expire, 1, 0); sqlite3VdbeAddOp(v, OP_Halt, 0, 0); |
︙ | ︙ | |||
51 52 53 54 55 56 57 | if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction"); pParse->rc = SQLITE_ERROR; return; } | | | > > < < > | > > | | < | > > | > > > | 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 | if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction"); pParse->rc = SQLITE_ERROR; return; } zFile = sqlite3NameFromToken(pFilename); if( zFile==0 ){ goto attach_end; } #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){ goto attach_end; } #endif /* SQLITE_OMIT_AUTHORIZATION */ zName = sqlite3NameFromToken(pDbname); if( zName==0 ){ goto attach_end; } for(i=0; i<db->nDb; i++){ char *z = db->aDb[i].zName; if( z && sqlite3StrICmp(z, zName)==0 ){ sqlite3ErrorMsg(pParse, "database %s is already in use", zName); pParse->rc = SQLITE_ERROR; goto attach_end; } } if( db->aDb==db->aDbStatic ){ aNew = sqliteMalloc( sizeof(db->aDb[0])*3 ); if( aNew==0 ){ goto attach_end; } memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); if( aNew==0 ){ goto attach_end; } } db->aDb = aNew; aNew = &db->aDb[db->nDb++]; memset(aNew, 0, sizeof(*aNew)); sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1); aNew->zName = zName; zName = 0; aNew->safety_level = 3; rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt); if( rc ){ sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile); } #if SQLITE_HAS_CODEC { |
︙ | ︙ | |||
122 123 124 125 126 127 128 | } sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); if( keyType ){ sqliteFree(zKey); } } #endif | < > > > > | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | } sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); if( keyType ){ sqliteFree(zKey); } } #endif db->flags &= ~SQLITE_Initialized; if( pParse->nErr==0 && rc==SQLITE_OK ){ rc = sqlite3ReadSchema(pParse); } if( rc ){ int i = db->nDb - 1; assert( i>=2 ); if( db->aDb[i].pBt ){ sqlite3BtreeClose(db->aDb[i].pBt); db->aDb[i].pBt = 0; } sqlite3ResetInternalSchema(db, 0); if( 0==pParse->nErr ){ pParse->nErr++; pParse->rc = SQLITE_ERROR; } } attach_end: sqliteFree(zFile); sqliteFree(zName); } /* ** This routine is called by the parser to process a DETACH statement: ** ** DETACH DATABASE dbname ** |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.313 2005/03/16 12:15:21 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. |
︙ | ︙ | |||
830 831 832 833 834 835 836 | sqliteFree(z); return; } } if( (p->nCol & 0x7)==0 ){ Column *aNew; aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0])); | | > > > | 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 | sqliteFree(z); return; } } if( (p->nCol & 0x7)==0 ){ Column *aNew; aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0])); if( aNew==0 ){ sqliteFree(z); return; } p->aCol = aNew; } pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; /* If there is no type specified, columns have the default affinity |
︙ | ︙ | |||
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 | CollSeq *pColl; if( nName<0 ) nName = strlen(zName); pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); if( 0==pColl && create ){ pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 ); if( pColl ){ pColl[0].zName = (char*)&pColl[3]; pColl[0].enc = SQLITE_UTF8; pColl[1].zName = (char*)&pColl[3]; pColl[1].enc = SQLITE_UTF16LE; pColl[2].zName = (char*)&pColl[3]; pColl[2].enc = SQLITE_UTF16BE; memcpy(pColl[0].zName, zName, nName); pColl[0].zName[nName] = 0; | > | > > > > > > > | 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 | CollSeq *pColl; if( nName<0 ) nName = strlen(zName); pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); if( 0==pColl && create ){ pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 ); if( pColl ){ CollSeq *pDel = 0; pColl[0].zName = (char*)&pColl[3]; pColl[0].enc = SQLITE_UTF8; pColl[1].zName = (char*)&pColl[3]; pColl[1].enc = SQLITE_UTF16LE; pColl[2].zName = (char*)&pColl[3]; pColl[2].enc = SQLITE_UTF16BE; memcpy(pColl[0].zName, zName, nName); pColl[0].zName[nName] = 0; pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); /* If a malloc() failure occured in sqlite3HashInsert(), it will ** return the pColl pointer to be deleted (because it wasn't added ** to the hash table). */ assert( !pDel || (sqlite3_malloc_failed && pDel==pColl) ); sqliteFree(pDel); } } return pColl; } /* ** Parameter zName points to a UTF-8 encoded string nName bytes long. |
︙ | ︙ | |||
2505 2506 2507 2508 2509 2510 2511 | ** implements the DROP INDEX statement. */ void sqlite3DropIndex(Parse *pParse, SrcList *pName){ Index *pIndex; Vdbe *v; sqlite3 *db = pParse->db; | | > > | > > | 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 | ** implements the DROP INDEX statement. */ void sqlite3DropIndex(Parse *pParse, SrcList *pName){ Index *pIndex; Vdbe *v; sqlite3 *db = pParse->db; if( pParse->nErr || sqlite3_malloc_failed ){ goto exit_drop_index; } assert( pName->nSrc==1 ); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; } pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); if( pIndex==0 ){ sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); pParse->checkSchema = 1; goto exit_drop_index; } if( pIndex->autoIndex ){ |
︙ | ︙ |
Changes to src/delete.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 C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** ** $Id: delete.c,v 1.102 2005/03/16 12:15:21 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, ** add an error message to pParse->zErrMsg and return NULL. If all tables ** are found, return a pointer to the last table. |
︙ | ︙ | |||
95 96 97 98 99 100 101 | #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ int triggers_exist = 0; /* True if any triggers exist */ #endif sContext.pParse = 0; if( pParse->nErr || sqlite3_malloc_failed ){ | < | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ int triggers_exist = 0; /* True if any triggers exist */ #endif sContext.pParse = 0; if( pParse->nErr || sqlite3_malloc_failed ){ goto delete_from_cleanup; } db = pParse->db; assert( pTabList->nSrc==1 ); /* Locate the table which we want to delete. This table has to be ** put in an SrcList structure because some of the subroutines we |
︙ | ︙ |
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 | ** 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.196 2005/03/16 12:15:21 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
179 180 181 182 183 184 185 | ** for this node is obtained from sqliteMalloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ Expr *pNew; pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ | | > > > > > | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | ** for this node is obtained from sqliteMalloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ Expr *pNew; pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ /* When malloc fails, delete pLeft and pRight. Expressions passed to ** this function must always be allocated with sqlite3Expr() for this ** reason. */ sqlite3ExprDelete(pLeft); sqlite3ExprDelete(pRight); return 0; } pNew->op = op; pNew->pLeft = pLeft; pNew->pRight = pRight; pNew->iAgg = -1; if( pToken ){ |
︙ | ︙ | |||
271 272 273 274 275 276 277 | ** Construct a new expression node for a function with multiple ** arguments. */ Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){ Expr *pNew; pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ | | | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | ** Construct a new expression node for a function with multiple ** arguments. */ Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){ Expr *pNew; pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */ return 0; } pNew->op = TK_FUNCTION; pNew->pList = pList; if( pToken ){ assert( pToken->dyn==0 ); pNew->token = *pToken; |
︙ | ︙ | |||
489 490 491 492 493 494 495 | 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]) ); | | > > > | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | 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 ){ sqliteFree(pNew); 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; |
︙ | ︙ | |||
538 539 540 541 542 543 544 | ** Add a new element to the end of an expression list. If pList is ** initially NULL, then create a new expression list. */ ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){ if( pList==0 ){ pList = sqliteMalloc( sizeof(ExprList) ); if( pList==0 ){ | < | > | | | < | < > > > > > > > > | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 | ** Add a new element to the end of an expression list. If pList is ** initially NULL, then create a new expression list. */ ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){ if( pList==0 ){ pList = sqliteMalloc( sizeof(ExprList) ); if( pList==0 ){ goto no_mem; } assert( pList->nAlloc==0 ); } if( pList->nAlloc<=pList->nExpr ){ struct ExprList_item *a; int n = pList->nAlloc*2 + 4; a = sqliteRealloc(pList->a, n*sizeof(pList->a[0])); if( a==0 ){ goto no_mem; } pList->a = a; pList->nAlloc = n; } assert( pList->a!=0 ); if( pExpr || pName ){ struct ExprList_item *pItem = &pList->a[pList->nExpr++]; memset(pItem, 0, sizeof(*pItem)); pItem->pExpr = pExpr; pItem->zName = sqlite3NameFromToken(pName); } return pList; no_mem: /* Avoid leaking memory if malloc has failed. */ sqlite3ExprDelete(pExpr); sqlite3ExprListDelete(pList); return 0; } /* ** Delete an entire expression list. */ void sqlite3ExprListDelete(ExprList *pList){ int i; |
︙ | ︙ | |||
765 766 767 768 769 770 771 | NameContext *pTopNC = pNC; /* First namecontext in the list */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(pDbToken); zTab = sqlite3NameFromToken(pTableToken); zCol = sqlite3NameFromToken(pColumnToken); if( sqlite3_malloc_failed ){ | | | 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 | NameContext *pTopNC = pNC; /* First namecontext in the list */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(pDbToken); zTab = sqlite3NameFromToken(pTableToken); zCol = sqlite3NameFromToken(pColumnToken); if( sqlite3_malloc_failed ){ goto lookupname_end; } pExpr->iTable = -1; while( pNC && cnt==0 ){ SrcList *pSrcList = pNC->pSrcList; ExprList *pEList = pNC->pEList; |
︙ | ︙ | |||
943 944 945 946 947 948 949 950 951 952 953 954 955 956 | if( n>=sizeof(Bitmask)*8 ){ n = sizeof(Bitmask)*8-1; } assert( pMatch->iCursor==pExpr->iTable ); pMatch->colUsed |= 1<<n; } /* Clean up and return */ sqliteFree(zDb); sqliteFree(zTab); sqliteFree(zCol); sqlite3ExprDelete(pExpr->pLeft); pExpr->pLeft = 0; | > | 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 | if( n>=sizeof(Bitmask)*8 ){ n = sizeof(Bitmask)*8-1; } assert( pMatch->iCursor==pExpr->iTable ); pMatch->colUsed |= 1<<n; } lookupname_end: /* Clean up and return */ sqliteFree(zDb); sqliteFree(zTab); sqliteFree(zCol); sqlite3ExprDelete(pExpr->pLeft); pExpr->pLeft = 0; |
︙ | ︙ |
Changes to src/insert.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 C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** ** $Id: insert.c,v 1.137 2005/03/16 12:15:21 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** Set P3 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: |
︙ | ︙ | |||
709 710 711 712 713 714 715 | sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC); } insert_cleanup: sqlite3SrcListDelete(pTabList); | | | | 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 | sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC); } insert_cleanup: sqlite3SrcListDelete(pTabList); sqlite3ExprListDelete(pList); sqlite3SelectDelete(pSelect); sqlite3IdListDelete(pColumn); } /* ** Generate code to do a constraint check prior to an INSERT or an UPDATE. ** ** When this routine is called, the stack contains (from bottom to top) |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $Id: parse.y,v 1.168 2005/03/16 12:15:21 danielk1977 Exp $ */ %token_prefix TK_ %token_type {Token} %default_type {Token} %extra_argument {Parse *pParse} %syntax_error { if( pParse->zErrMsg==0 ){ |
︙ | ︙ | |||
708 709 710 711 712 713 714 | } %ifndef SQLITE_OMIT_SUBQUERY %type in_op {int} in_op(A) ::= IN. {A = 0;} in_op(A) ::= NOT IN. {A = 1;} expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] { A = sqlite3Expr(TK_IN, X, 0, 0); | > | > > > > > > | 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 | } %ifndef SQLITE_OMIT_SUBQUERY %type in_op {int} in_op(A) ::= IN. {A = 0;} in_op(A) ::= NOT IN. {A = 1;} expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] { A = sqlite3Expr(TK_IN, X, 0, 0); if( A ){ A->pList = Y; }else{ sqlite3ExprListDelete(Y); } if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= LP(B) select(X) RP(E). { A = sqlite3Expr(TK_SELECT, 0, 0, 0); if( A ) A->pSelect = X; if( !A ) sqlite3SelectDelete(X); sqlite3ExprSpan(A,&B,&E); } expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] { A = sqlite3Expr(TK_IN, X, 0, 0); if( A ) A->pSelect = Y; if( !A ) sqlite3SelectDelete(Y); if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] { SrcList *pSrc = sqlite3SrcListAppend(0,&Y,&Z); A = sqlite3Expr(TK_IN, X, 0, 0); if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y); } expr(A) ::= EXISTS(B) LP select(Y) RP(E). { Expr *p = A = sqlite3Expr(TK_EXISTS, 0, 0, 0); if( p ){ p->pSelect = Y; sqlite3ExprSpan(p,&B,&E); } if( !p ) sqlite3SelectDelete(Y); } %endif // SQLITE_OMIT_SUBQUERY /* CASE expressions */ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { A = sqlite3Expr(TK_CASE, X, Z, 0); if( A ) A->pList = Y; |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
47 48 49 50 51 52 53 | int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */ IdList *pColumns, /* column list if this is an UPDATE OF trigger */ SrcList *pTableName,/* The name of the table/view the trigger applies to */ int foreach, /* One of TK_ROW or TK_STATEMENT */ Expr *pWhen, /* WHEN clause */ int isTemp /* True if the TEMPORARY keyword is present */ ){ | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */ IdList *pColumns, /* column list if this is an UPDATE OF trigger */ SrcList *pTableName,/* The name of the table/view the trigger applies to */ int foreach, /* One of TK_ROW or TK_STATEMENT */ Expr *pWhen, /* WHEN clause */ int isTemp /* True if the TEMPORARY keyword is present */ ){ Trigger *pTrigger = 0; Table *pTab; char *zName = 0; /* Name of the trigger */ sqlite3 *db = pParse->db; int iDb; /* The database to store the trigger in */ Token *pName; /* The unqualified db name */ DbFixer sFix; |
︙ | ︙ | |||
157 158 159 160 161 162 163 | /* Build the Trigger object */ pTrigger = (Trigger*)sqliteMalloc(sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; pTrigger->name = zName; zName = 0; pTrigger->table = sqliteStrDup(pTableName->a[0].zName); | < > > > > > | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | /* Build the Trigger object */ pTrigger = (Trigger*)sqliteMalloc(sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; pTrigger->name = zName; zName = 0; pTrigger->table = sqliteStrDup(pTableName->a[0].zName); pTrigger->iDb = iDb; pTrigger->iTabDb = pTab->iDb; pTrigger->op = op; pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; pTrigger->pWhen = sqlite3ExprDup(pWhen); pTrigger->pColumns = sqlite3IdListDup(pColumns); pTrigger->foreach = foreach; sqlite3TokenCopy(&pTrigger->nameToken,pName); assert( pParse->pNewTrigger==0 ); pParse->pNewTrigger = pTrigger; trigger_cleanup: sqliteFree(zName); sqlite3SrcListDelete(pTableName); sqlite3IdListDelete(pColumns); sqlite3ExprDelete(pWhen); if( !pParse->pNewTrigger ){ sqlite3DeleteTrigger(pTrigger); }else{ assert( pParse->pNewTrigger==pTrigger ); } } /* ** This routine is called after all of the trigger actions have been parsed ** in order to complete the process of building the trigger. */ void sqlite3FinishTrigger( |
︙ | ︙ | |||
238 239 240 241 242 243 244 | sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3VdbeOp3(v, OP_ParseSchema, pTrig->iDb, 0, sqlite3MPrintf("type='trigger' AND name='%q'", pTrig->name), P3_DYNAMIC); } if( db->init.busy ){ Table *pTab; | > | > > > > | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3VdbeOp3(v, OP_ParseSchema, pTrig->iDb, 0, sqlite3MPrintf("type='trigger' AND name='%q'", pTrig->name), P3_DYNAMIC); } if( db->init.busy ){ Table *pTab; Trigger *pDel; pDel = sqlite3HashInsert(&db->aDb[pTrig->iDb].trigHash, pTrig->name, strlen(pTrig->name)+1, pTrig); if( pDel ){ assert( sqlite3_malloc_failed && pDel==pTrig ); goto triggerfinish_cleanup; } pTab = sqlite3LocateTable(pParse,pTrig->table,db->aDb[pTrig->iTabDb].zName); assert( pTab!=0 ); pTrig->pNext = pTab->pTrigger; pTab->pTrigger = pTrig; pTrig = 0; } |
︙ | ︙ | |||
324 325 326 327 328 329 330 | Token *pTableName, /* Name of the table into which we insert */ IdList *pColumn, /* List of columns in pTableName to insert into */ ExprList *pEList, /* The VALUE clause: a list of values to be inserted */ Select *pSelect, /* A SELECT statement that supplies values */ int orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ ){ TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep)); | < > > > > > > | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | Token *pTableName, /* Name of the table into which we insert */ IdList *pColumn, /* List of columns in pTableName to insert into */ ExprList *pEList, /* The VALUE clause: a list of values to be inserted */ Select *pSelect, /* A SELECT statement that supplies values */ int orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ ){ TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep)); assert(pEList == 0 || pSelect == 0); assert(pEList != 0 || pSelect != 0); if( pTriggerStep ){ pTriggerStep->op = TK_INSERT; pTriggerStep->pSelect = pSelect; pTriggerStep->target = *pTableName; pTriggerStep->pIdList = pColumn; pTriggerStep->pExprList = pEList; pTriggerStep->orconf = orconf; sqlitePersistTriggerStep(pTriggerStep); }else{ sqlite3IdListDelete(pColumn); sqlite3ExprListDelete(pEList); sqlite3SelectDup(pSelect); } return pTriggerStep; } /* ** Construct a trigger step that implements an UPDATE statement and return ** a pointer to that trigger step. The parser calls this routine when it |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
267 268 269 270 271 272 273 | ** from sqliteMalloc. ** ** If addr<0 then change P3 on the most recently inserted instruction. */ void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){ Op *pOp; assert( p->magic==VDBE_MAGIC_INIT ); | | > > > > > | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | ** from sqliteMalloc. ** ** If addr<0 then change P3 on the most recently inserted instruction. */ void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){ Op *pOp; assert( p->magic==VDBE_MAGIC_INIT ); if( p==0 || p->aOp==0 ){ if( n==P3_DYNAMIC || n==P3_KEYINFO_HANDOFF ){ sqliteFree(zP3); } return; } if( addr<0 || addr>=p->nOp ){ addr = p->nOp - 1; if( addr<0 ) return; } pOp = &p->aOp[addr]; if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){ sqliteFree(pOp->p3); |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.136 2005/03/16 12:15:21 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The query generator uses an array of instances of this structure to ** help it analyze the subexpressions of the WHERE clause. Each WHERE ** clause subexpression is separated from the others by an AND operator. |
︙ | ︙ | |||
641 642 643 644 645 646 647 | } /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel)); if( sqlite3_malloc_failed ){ | | | 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 | } /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel)); if( sqlite3_malloc_failed ){ sqliteFree(pWInfo); /* Avoid leaking memory when malloc fails */ return 0; } pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->iBreak = sqlite3VdbeMakeLabel(v); /* Special case: a WHERE clause that is constant. Evaluate the |
︙ | ︙ |
Changes to test/memleak.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 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. # #*********************************************************************** # This file runs all tests. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 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. # #*********************************************************************** # This file runs all tests. # # $Id: memleak.test,v 1.9 2005/03/16 12:15:22 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl rename finish_test really_finish_test proc finish_test {} { catch {db close} memleak_check |
︙ | ︙ | |||
31 32 33 34 35 36 37 | # grows, it may mean there is a memory leak in the library. # set LeakList {} set EXCLUDE { all.test quick.test | < | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | # grows, it may mean there is a memory leak in the library. # set LeakList {} set EXCLUDE { all.test quick.test misuse.test memleak.test btree2.test trans.test crash.test autovacuum_crash.test } |
︙ | ︙ |