mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Fix some memory leaks that can occur if a memory allocation fails. (CVS 2388)
FossilOrigin-Name: 9a358fc33d726d0b5782bf65b50f61f2bd096d56
This commit is contained in:
32
manifest
32
manifest
@@ -1,5 +1,5 @@
|
|||||||
C When\screating\sa\snew\sdatabase,\sdelete\sany\spreexisting\sjournal\sthat\smight\sbe\nleft\sover\sfrom\sa\sprior\sdatabase\swith\sthe\ssame\sname.\s\sTicket\s#1152.\s(CVS\s2387)
|
C Fix\ssome\smemory\sleaks\sthat\scan\soccur\sif\sa\smemory\sallocation\sfails.\s(CVS\s2388)
|
||||||
D 2005-03-15T17:09:30
|
D 2005-03-16T12:15:21
|
||||||
F Makefile.in 5c00d0037104de2a50ac7647a5f12769795957a3
|
F Makefile.in 5c00d0037104de2a50ac7647a5f12769795957a3
|
||||||
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
|
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
|
||||||
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
|
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
|
||||||
@@ -28,19 +28,19 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
|||||||
F sqlite3.def dbaeb20c153e1d366e8f421b55a573f5dfc00863
|
F sqlite3.def dbaeb20c153e1d366e8f421b55a573f5dfc00863
|
||||||
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
|
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
|
||||||
F src/alter.c 6dab3d91aa4bf5c24e874145a2a547070c8c1883
|
F src/alter.c 6dab3d91aa4bf5c24e874145a2a547070c8c1883
|
||||||
F src/attach.c 43099c31dfa82b77e671918fc5565ae7ea211af1
|
F src/attach.c 3615dbe960cbee4aa5ea300b8a213dad36527b0f
|
||||||
F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f
|
F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f
|
||||||
F src/btree.c 1d9b2179ccac13970c883da6ae3758cc72978bb0
|
F src/btree.c 1d9b2179ccac13970c883da6ae3758cc72978bb0
|
||||||
F src/btree.h 2e2cc923224649337d7217df0dd32b06673ca180
|
F src/btree.h 2e2cc923224649337d7217df0dd32b06673ca180
|
||||||
F src/build.c a8792b2f866c1ccc32f4977f4ff61d787d60ddfb
|
F src/build.c 66bf13d2d478d43b9b490bebf07ea62524d80993
|
||||||
F src/date.c f3d1f5cd1503dabf426a198f3ebef5afbc122a7f
|
F src/date.c f3d1f5cd1503dabf426a198f3ebef5afbc122a7f
|
||||||
F src/delete.c ebd18402d5c4dcc410043dacc831fe3e1ad8480a
|
F src/delete.c d70d54a84695de92efc05b9db7d3684cd21d9094
|
||||||
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
|
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
|
||||||
F src/expr.c 8901081a1207ce7fc038bdc1d97ec4f102a7bfd9
|
F src/expr.c 53f854495411eed41e42ec7f174aef64b7918119
|
||||||
F src/func.c ff0673a25ec6216934e664bf9f480ae8b2c66936
|
F src/func.c ff0673a25ec6216934e664bf9f480ae8b2c66936
|
||||||
F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f
|
F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f
|
||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||||
F src/insert.c 0456649d4d48396f918e7ea1fecbf3d66ed90816
|
F src/insert.c 7e6b123bdb3fd45a907361b1bcc2e56e66fdd0ed
|
||||||
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
||||||
F src/main.c 90cb84bbb85aa89442af41ad4323b136af6527b7
|
F src/main.c 90cb84bbb85aa89442af41ad4323b136af6527b7
|
||||||
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
||||||
@@ -54,7 +54,7 @@ F src/os_win.c bddeae1c3299be0fbe47077dd4e98b786a067f71
|
|||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c 26a642c1238615bdea53d458ab6a4df7ca070a08
|
F src/pager.c 26a642c1238615bdea53d458ab6a4df7ca070a08
|
||||||
F src/pager.h 70d496f372163abb6340f474288c4bb9ea962cf7
|
F src/pager.h 70d496f372163abb6340f474288c4bb9ea962cf7
|
||||||
F src/parse.y 0b6135268a7a29db35335d5b71b5a8791e02f91e
|
F src/parse.y 5c8336e7df0d843976c2aa0f63010d479d9cdba5
|
||||||
F src/pragma.c 4b20dbc0f4b97f412dc511853d3d0c2e0d4adedc
|
F src/pragma.c 4b20dbc0f4b97f412dc511853d3d0c2e0d4adedc
|
||||||
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
|
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
|
||||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||||
@@ -70,7 +70,7 @@ F src/test3.c 683e1e3819152ffd35da2f201e507228921148d0
|
|||||||
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
||||||
F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5
|
F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5
|
||||||
F src/tokenize.c 103cbaa932c790f540f8eceb63cd3010e117bdff
|
F src/tokenize.c 103cbaa932c790f540f8eceb63cd3010e117bdff
|
||||||
F src/trigger.c 038c8e128d4551cd016426cd11bbf5c478816481
|
F src/trigger.c 0c3ec8a6cb7176aaecc3978bfc34050ec1a852c4
|
||||||
F src/update.c 42823d00865c9fe4f01b3c62647858726345a28e
|
F src/update.c 42823d00865c9fe4f01b3c62647858726345a28e
|
||||||
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
|
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
|
||||||
F src/util.c a53b6fc6f09093ecba1ce593ca7cb1cb77b3a20b
|
F src/util.c a53b6fc6f09093ecba1ce593ca7cb1cb77b3a20b
|
||||||
@@ -79,9 +79,9 @@ F src/vdbe.c 1bf34fb915afffd9b865a81770dc8cb99b3a04ac
|
|||||||
F src/vdbe.h 7e307333d74e134eff237bb9d45fe764e544ad6a
|
F src/vdbe.h 7e307333d74e134eff237bb9d45fe764e544ad6a
|
||||||
F src/vdbeInt.h e80721cd8ff611789e20743eec43363a9fb5a48e
|
F src/vdbeInt.h e80721cd8ff611789e20743eec43363a9fb5a48e
|
||||||
F src/vdbeapi.c 467caa6e6fb9247528b1c7ab9132ae1b4748e8ac
|
F src/vdbeapi.c 467caa6e6fb9247528b1c7ab9132ae1b4748e8ac
|
||||||
F src/vdbeaux.c 30a9a6f6c80c7862e23c741a99c27e75149b39f5
|
F src/vdbeaux.c 3c2f1d5df1ac21e20a9795f4a988f663b01f7b83
|
||||||
F src/vdbemem.c 4e853ce3151eaf7906150da85a1b3ce1fe5e8da8
|
F src/vdbemem.c 4e853ce3151eaf7906150da85a1b3ce1fe5e8da8
|
||||||
F src/where.c 80a2a9d24f868fc5744ba2838701c46934c7e09f
|
F src/where.c c4b227458e8993decb515ed9a2fe2d4f5f8e3125
|
||||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||||
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
|
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
|
||||||
F test/alter.test 3a20ce14c3989f7e2e75da50797065c2e56f838b
|
F test/alter.test 3a20ce14c3989f7e2e75da50797065c2e56f838b
|
||||||
@@ -154,7 +154,7 @@ F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
|
|||||||
F test/main.test febb69416071134dc38b9b1971c0c2e5b0ca3ff8
|
F test/main.test febb69416071134dc38b9b1971c0c2e5b0ca3ff8
|
||||||
F test/malloc.test b7bc72bb1627e09d6003f58de9bcd6e4be839753
|
F test/malloc.test b7bc72bb1627e09d6003f58de9bcd6e4be839753
|
||||||
F test/memdb.test 1860e060be810bf0775bc57408a5b7c4954bcaea
|
F test/memdb.test 1860e060be810bf0775bc57408a5b7c4954bcaea
|
||||||
F test/memleak.test c0af09191af44a7501ec2494fdd079ac538a256c
|
F test/memleak.test df2b2b96e77f8ba159a332299535b1e5f18e49ac
|
||||||
F test/minmax.test 9429a06f1f93acf76fcacafd17160a4392e88526
|
F test/minmax.test 9429a06f1f93acf76fcacafd17160a4392e88526
|
||||||
F test/misc1.test ff817d3740458884fea535b44821ec7e84700457
|
F test/misc1.test ff817d3740458884fea535b44821ec7e84700457
|
||||||
F test/misc2.test fc052267d5178367f955538ae34aae1b2f696a92
|
F test/misc2.test fc052267d5178367f955538ae34aae1b2f696a92
|
||||||
@@ -275,7 +275,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||||
F www/whentouse.tcl 3e522a06ad41992023c80ca29a048ae2331ca5bd
|
F www/whentouse.tcl 3e522a06ad41992023c80ca29a048ae2331ca5bd
|
||||||
P 24e887735256499e58dabe90463524d9e6eb08ce
|
P 856e2ec9688affbfe496cf184f460b18408e3dc0
|
||||||
R 76fc7bf07ced1da0a2aa6b133619eb70
|
R bdf8d1650bfb73f4118211dfe43d3498
|
||||||
U drh
|
U danielk1977
|
||||||
Z 568a4e730d583509fc67f9b125ab2918
|
Z c63eb3de507eaddae37da59fce3b144c
|
||||||
|
@@ -1 +1 @@
|
|||||||
856e2ec9688affbfe496cf184f460b18408e3dc0
|
9a358fc33d726d0b5782bf65b50f61f2bd096d56
|
37
src/attach.c
37
src/attach.c
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the ATTACH and DETACH commands.
|
** This file contains code used to implement the ATTACH and DETACH commands.
|
||||||
**
|
**
|
||||||
** $Id: attach.c,v 1.32 2005/03/15 02:04:12 drh Exp $
|
** $Id: attach.c,v 1.33 2005/03/16 12:15:21 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -32,7 +32,8 @@ void sqlite3Attach(
|
|||||||
){
|
){
|
||||||
Db *aNew;
|
Db *aNew;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
char *zFile, *zName;
|
char *zFile = 0;
|
||||||
|
char *zName = 0;
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
|
|
||||||
@@ -55,34 +56,40 @@ void sqlite3Attach(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
zFile = sqlite3NameFromToken(pFilename);;
|
zFile = sqlite3NameFromToken(pFilename);
|
||||||
if( zFile==0 ) return;
|
if( zFile==0 ){
|
||||||
|
goto attach_end;
|
||||||
|
}
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
|
if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
|
||||||
sqliteFree(zFile);
|
goto attach_end;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
||||||
|
|
||||||
zName = sqlite3NameFromToken(pDbname);
|
zName = sqlite3NameFromToken(pDbname);
|
||||||
if( zName==0 ) return;
|
if( zName==0 ){
|
||||||
|
goto attach_end;
|
||||||
|
}
|
||||||
for(i=0; i<db->nDb; i++){
|
for(i=0; i<db->nDb; i++){
|
||||||
char *z = db->aDb[i].zName;
|
char *z = db->aDb[i].zName;
|
||||||
if( z && sqlite3StrICmp(z, zName)==0 ){
|
if( z && sqlite3StrICmp(z, zName)==0 ){
|
||||||
sqlite3ErrorMsg(pParse, "database %z is already in use", zName);
|
sqlite3ErrorMsg(pParse, "database %s is already in use", zName);
|
||||||
pParse->rc = SQLITE_ERROR;
|
pParse->rc = SQLITE_ERROR;
|
||||||
sqliteFree(zFile);
|
goto attach_end;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( db->aDb==db->aDbStatic ){
|
if( db->aDb==db->aDbStatic ){
|
||||||
aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
|
aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
|
||||||
if( aNew==0 ) return;
|
if( aNew==0 ){
|
||||||
|
goto attach_end;
|
||||||
|
}
|
||||||
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
|
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
|
||||||
}else{
|
}else{
|
||||||
aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
|
aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
|
||||||
if( aNew==0 ) return;
|
if( aNew==0 ){
|
||||||
|
goto attach_end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
db->aDb = aNew;
|
db->aDb = aNew;
|
||||||
aNew = &db->aDb[db->nDb++];
|
aNew = &db->aDb[db->nDb++];
|
||||||
@@ -92,6 +99,7 @@ void sqlite3Attach(
|
|||||||
sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
|
sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
|
||||||
sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
|
sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
|
||||||
aNew->zName = zName;
|
aNew->zName = zName;
|
||||||
|
zName = 0;
|
||||||
aNew->safety_level = 3;
|
aNew->safety_level = 3;
|
||||||
rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
|
rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
@@ -126,7 +134,6 @@ void sqlite3Attach(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
sqliteFree(zFile);
|
|
||||||
db->flags &= ~SQLITE_Initialized;
|
db->flags &= ~SQLITE_Initialized;
|
||||||
if( pParse->nErr==0 && rc==SQLITE_OK ){
|
if( pParse->nErr==0 && rc==SQLITE_OK ){
|
||||||
rc = sqlite3ReadSchema(pParse);
|
rc = sqlite3ReadSchema(pParse);
|
||||||
@@ -144,6 +151,10 @@ void sqlite3Attach(
|
|||||||
pParse->rc = SQLITE_ERROR;
|
pParse->rc = SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attach_end:
|
||||||
|
sqliteFree(zFile);
|
||||||
|
sqliteFree(zName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
25
src/build.c
25
src/build.c
@@ -22,7 +22,7 @@
|
|||||||
** COMMIT
|
** COMMIT
|
||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.312 2005/02/19 08:18:06 danielk1977 Exp $
|
** $Id: build.c,v 1.313 2005/03/16 12:15:21 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -834,7 +834,10 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){
|
|||||||
if( (p->nCol & 0x7)==0 ){
|
if( (p->nCol & 0x7)==0 ){
|
||||||
Column *aNew;
|
Column *aNew;
|
||||||
aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
|
aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
|
||||||
if( aNew==0 ) return;
|
if( aNew==0 ){
|
||||||
|
sqliteFree(z);
|
||||||
|
return;
|
||||||
|
}
|
||||||
p->aCol = aNew;
|
p->aCol = aNew;
|
||||||
}
|
}
|
||||||
pCol = &p->aCol[p->nCol];
|
pCol = &p->aCol[p->nCol];
|
||||||
@@ -1095,6 +1098,7 @@ static CollSeq * findCollSeqEntry(
|
|||||||
if( 0==pColl && create ){
|
if( 0==pColl && create ){
|
||||||
pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );
|
pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );
|
||||||
if( pColl ){
|
if( pColl ){
|
||||||
|
CollSeq *pDel = 0;
|
||||||
pColl[0].zName = (char*)&pColl[3];
|
pColl[0].zName = (char*)&pColl[3];
|
||||||
pColl[0].enc = SQLITE_UTF8;
|
pColl[0].enc = SQLITE_UTF8;
|
||||||
pColl[1].zName = (char*)&pColl[3];
|
pColl[1].zName = (char*)&pColl[3];
|
||||||
@@ -1103,7 +1107,14 @@ static CollSeq * findCollSeqEntry(
|
|||||||
pColl[2].enc = SQLITE_UTF16BE;
|
pColl[2].enc = SQLITE_UTF16BE;
|
||||||
memcpy(pColl[0].zName, zName, nName);
|
memcpy(pColl[0].zName, zName, nName);
|
||||||
pColl[0].zName[nName] = 0;
|
pColl[0].zName[nName] = 0;
|
||||||
sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
|
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;
|
return pColl;
|
||||||
@@ -2509,9 +2520,13 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){
|
|||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
sqlite3 *db = pParse->db;
|
sqlite3 *db = pParse->db;
|
||||||
|
|
||||||
if( pParse->nErr || sqlite3_malloc_failed ) return;
|
if( pParse->nErr || sqlite3_malloc_failed ){
|
||||||
|
goto exit_drop_index;
|
||||||
|
}
|
||||||
assert( pName->nSrc==1 );
|
assert( pName->nSrc==1 );
|
||||||
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) return;
|
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
|
||||||
|
goto exit_drop_index;
|
||||||
|
}
|
||||||
pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
|
pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
|
||||||
if( pIndex==0 ){
|
if( pIndex==0 ){
|
||||||
sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
|
sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** in order to generate code for DELETE FROM statements.
|
** in order to generate code for DELETE FROM statements.
|
||||||
**
|
**
|
||||||
** $Id: delete.c,v 1.101 2005/03/09 12:26:51 danielk1977 Exp $
|
** $Id: delete.c,v 1.102 2005/03/16 12:15:21 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -99,7 +99,6 @@ void sqlite3DeleteFrom(
|
|||||||
|
|
||||||
sContext.pParse = 0;
|
sContext.pParse = 0;
|
||||||
if( pParse->nErr || sqlite3_malloc_failed ){
|
if( pParse->nErr || sqlite3_malloc_failed ){
|
||||||
pTabList = 0;
|
|
||||||
goto delete_from_cleanup;
|
goto delete_from_cleanup;
|
||||||
}
|
}
|
||||||
db = pParse->db;
|
db = pParse->db;
|
||||||
|
41
src/expr.c
41
src/expr.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** for generating VDBE code that evaluates expressions in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: expr.c,v 1.195 2005/03/09 12:26:51 danielk1977 Exp $
|
** $Id: expr.c,v 1.196 2005/03/16 12:15:21 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -183,7 +183,12 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){
|
|||||||
Expr *pNew;
|
Expr *pNew;
|
||||||
pNew = sqliteMalloc( sizeof(Expr) );
|
pNew = sqliteMalloc( sizeof(Expr) );
|
||||||
if( pNew==0 ){
|
if( pNew==0 ){
|
||||||
/* When malloc fails, we leak memory from pLeft and pRight */
|
/* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
pNew->op = op;
|
pNew->op = op;
|
||||||
@@ -275,7 +280,7 @@ Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){
|
|||||||
Expr *pNew;
|
Expr *pNew;
|
||||||
pNew = sqliteMalloc( sizeof(Expr) );
|
pNew = sqliteMalloc( sizeof(Expr) );
|
||||||
if( pNew==0 ){
|
if( pNew==0 ){
|
||||||
/* sqlite3ExprListDelete(pList); // Leak pList when malloc fails */
|
sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pNew->op = TK_FUNCTION;
|
pNew->op = TK_FUNCTION;
|
||||||
@@ -493,7 +498,10 @@ IdList *sqlite3IdListDup(IdList *p){
|
|||||||
if( pNew==0 ) return 0;
|
if( pNew==0 ) return 0;
|
||||||
pNew->nId = pNew->nAlloc = p->nId;
|
pNew->nId = pNew->nAlloc = p->nId;
|
||||||
pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) );
|
pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) );
|
||||||
if( pNew->a==0 ) return 0;
|
if( pNew->a==0 ){
|
||||||
|
sqliteFree(pNew);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
for(i=0; i<p->nId; i++){
|
for(i=0; i<p->nId; i++){
|
||||||
struct IdList_item *pNewItem = &pNew->a[i];
|
struct IdList_item *pNewItem = &pNew->a[i];
|
||||||
struct IdList_item *pOldItem = &p->a[i];
|
struct IdList_item *pOldItem = &p->a[i];
|
||||||
@@ -542,19 +550,19 @@ ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
|
|||||||
if( pList==0 ){
|
if( pList==0 ){
|
||||||
pList = sqliteMalloc( sizeof(ExprList) );
|
pList = sqliteMalloc( sizeof(ExprList) );
|
||||||
if( pList==0 ){
|
if( pList==0 ){
|
||||||
/* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */
|
goto no_mem;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
assert( pList->nAlloc==0 );
|
assert( pList->nAlloc==0 );
|
||||||
}
|
}
|
||||||
if( pList->nAlloc<=pList->nExpr ){
|
if( pList->nAlloc<=pList->nExpr ){
|
||||||
pList->nAlloc = pList->nAlloc*2 + 4;
|
struct ExprList_item *a;
|
||||||
pList->a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]));
|
int n = pList->nAlloc*2 + 4;
|
||||||
if( pList->a==0 ){
|
a = sqliteRealloc(pList->a, n*sizeof(pList->a[0]));
|
||||||
/* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */
|
if( a==0 ){
|
||||||
pList->nExpr = pList->nAlloc = 0;
|
goto no_mem;
|
||||||
return pList;
|
|
||||||
}
|
}
|
||||||
|
pList->a = a;
|
||||||
|
pList->nAlloc = n;
|
||||||
}
|
}
|
||||||
assert( pList->a!=0 );
|
assert( pList->a!=0 );
|
||||||
if( pExpr || pName ){
|
if( pExpr || pName ){
|
||||||
@@ -564,6 +572,12 @@ ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
|
|||||||
pItem->zName = sqlite3NameFromToken(pName);
|
pItem->zName = sqlite3NameFromToken(pName);
|
||||||
}
|
}
|
||||||
return pList;
|
return pList;
|
||||||
|
|
||||||
|
no_mem:
|
||||||
|
/* Avoid leaking memory if malloc has failed. */
|
||||||
|
sqlite3ExprDelete(pExpr);
|
||||||
|
sqlite3ExprListDelete(pList);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -769,7 +783,7 @@ static int lookupName(
|
|||||||
zTab = sqlite3NameFromToken(pTableToken);
|
zTab = sqlite3NameFromToken(pTableToken);
|
||||||
zCol = sqlite3NameFromToken(pColumnToken);
|
zCol = sqlite3NameFromToken(pColumnToken);
|
||||||
if( sqlite3_malloc_failed ){
|
if( sqlite3_malloc_failed ){
|
||||||
return 1; /* Leak memory (zDb and zTab) if malloc fails */
|
goto lookupname_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
pExpr->iTable = -1;
|
pExpr->iTable = -1;
|
||||||
@@ -947,6 +961,7 @@ static int lookupName(
|
|||||||
pMatch->colUsed |= 1<<n;
|
pMatch->colUsed |= 1<<n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lookupname_end:
|
||||||
/* Clean up and return
|
/* Clean up and return
|
||||||
*/
|
*/
|
||||||
sqliteFree(zDb);
|
sqliteFree(zDb);
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle INSERT statements in SQLite.
|
** to handle INSERT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: insert.c,v 1.136 2005/02/08 08:42:28 danielk1977 Exp $
|
** $Id: insert.c,v 1.137 2005/03/16 12:15:21 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -713,8 +713,8 @@ void sqlite3Insert(
|
|||||||
|
|
||||||
insert_cleanup:
|
insert_cleanup:
|
||||||
sqlite3SrcListDelete(pTabList);
|
sqlite3SrcListDelete(pTabList);
|
||||||
if( pList ) sqlite3ExprListDelete(pList);
|
sqlite3ExprListDelete(pList);
|
||||||
if( pSelect ) sqlite3SelectDelete(pSelect);
|
sqlite3SelectDelete(pSelect);
|
||||||
sqlite3IdListDelete(pColumn);
|
sqlite3IdListDelete(pColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
src/parse.y
11
src/parse.y
@@ -14,7 +14,7 @@
|
|||||||
** the parser. Lemon will also generate a header file containing
|
** the parser. Lemon will also generate a header file containing
|
||||||
** numeric codes for all of the tokens.
|
** numeric codes for all of the tokens.
|
||||||
**
|
**
|
||||||
** @(#) $Id: parse.y,v 1.167 2005/03/09 12:26:51 danielk1977 Exp $
|
** @(#) $Id: parse.y,v 1.168 2005/03/16 12:15:21 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
%token_prefix TK_
|
%token_prefix TK_
|
||||||
%token_type {Token}
|
%token_type {Token}
|
||||||
@@ -712,18 +712,24 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
|||||||
in_op(A) ::= NOT IN. {A = 1;}
|
in_op(A) ::= NOT IN. {A = 1;}
|
||||||
expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] {
|
expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] {
|
||||||
A = sqlite3Expr(TK_IN, X, 0, 0);
|
A = sqlite3Expr(TK_IN, X, 0, 0);
|
||||||
if( A ) A->pList = Y;
|
if( A ){
|
||||||
|
A->pList = Y;
|
||||||
|
}else{
|
||||||
|
sqlite3ExprListDelete(Y);
|
||||||
|
}
|
||||||
if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
|
if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
|
||||||
sqlite3ExprSpan(A,&X->span,&E);
|
sqlite3ExprSpan(A,&X->span,&E);
|
||||||
}
|
}
|
||||||
expr(A) ::= LP(B) select(X) RP(E). {
|
expr(A) ::= LP(B) select(X) RP(E). {
|
||||||
A = sqlite3Expr(TK_SELECT, 0, 0, 0);
|
A = sqlite3Expr(TK_SELECT, 0, 0, 0);
|
||||||
if( A ) A->pSelect = X;
|
if( A ) A->pSelect = X;
|
||||||
|
if( !A ) sqlite3SelectDelete(X);
|
||||||
sqlite3ExprSpan(A,&B,&E);
|
sqlite3ExprSpan(A,&B,&E);
|
||||||
}
|
}
|
||||||
expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] {
|
expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] {
|
||||||
A = sqlite3Expr(TK_IN, X, 0, 0);
|
A = sqlite3Expr(TK_IN, X, 0, 0);
|
||||||
if( A ) A->pSelect = Y;
|
if( A ) A->pSelect = Y;
|
||||||
|
if( !A ) sqlite3SelectDelete(Y);
|
||||||
if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
|
if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
|
||||||
sqlite3ExprSpan(A,&X->span,&E);
|
sqlite3ExprSpan(A,&X->span,&E);
|
||||||
}
|
}
|
||||||
@@ -740,6 +746,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
|||||||
p->pSelect = Y;
|
p->pSelect = Y;
|
||||||
sqlite3ExprSpan(p,&B,&E);
|
sqlite3ExprSpan(p,&B,&E);
|
||||||
}
|
}
|
||||||
|
if( !p ) sqlite3SelectDelete(Y);
|
||||||
}
|
}
|
||||||
%endif // SQLITE_OMIT_SUBQUERY
|
%endif // SQLITE_OMIT_SUBQUERY
|
||||||
|
|
||||||
|
@@ -51,7 +51,7 @@ void sqlite3BeginTrigger(
|
|||||||
Expr *pWhen, /* WHEN clause */
|
Expr *pWhen, /* WHEN clause */
|
||||||
int isTemp /* True if the TEMPORARY keyword is present */
|
int isTemp /* True if the TEMPORARY keyword is present */
|
||||||
){
|
){
|
||||||
Trigger *pTrigger;
|
Trigger *pTrigger = 0;
|
||||||
Table *pTab;
|
Table *pTab;
|
||||||
char *zName = 0; /* Name of the trigger */
|
char *zName = 0; /* Name of the trigger */
|
||||||
sqlite3 *db = pParse->db;
|
sqlite3 *db = pParse->db;
|
||||||
@@ -161,7 +161,6 @@ void sqlite3BeginTrigger(
|
|||||||
pTrigger->name = zName;
|
pTrigger->name = zName;
|
||||||
zName = 0;
|
zName = 0;
|
||||||
pTrigger->table = sqliteStrDup(pTableName->a[0].zName);
|
pTrigger->table = sqliteStrDup(pTableName->a[0].zName);
|
||||||
if( sqlite3_malloc_failed ) goto trigger_cleanup;
|
|
||||||
pTrigger->iDb = iDb;
|
pTrigger->iDb = iDb;
|
||||||
pTrigger->iTabDb = pTab->iDb;
|
pTrigger->iTabDb = pTab->iDb;
|
||||||
pTrigger->op = op;
|
pTrigger->op = op;
|
||||||
@@ -178,6 +177,11 @@ trigger_cleanup:
|
|||||||
sqlite3SrcListDelete(pTableName);
|
sqlite3SrcListDelete(pTableName);
|
||||||
sqlite3IdListDelete(pColumns);
|
sqlite3IdListDelete(pColumns);
|
||||||
sqlite3ExprDelete(pWhen);
|
sqlite3ExprDelete(pWhen);
|
||||||
|
if( !pParse->pNewTrigger ){
|
||||||
|
sqlite3DeleteTrigger(pTrigger);
|
||||||
|
}else{
|
||||||
|
assert( pParse->pNewTrigger==pTrigger );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -242,8 +246,13 @@ void sqlite3FinishTrigger(
|
|||||||
|
|
||||||
if( db->init.busy ){
|
if( db->init.busy ){
|
||||||
Table *pTab;
|
Table *pTab;
|
||||||
sqlite3HashInsert(&db->aDb[pTrig->iDb].trigHash,
|
Trigger *pDel;
|
||||||
|
pDel = sqlite3HashInsert(&db->aDb[pTrig->iDb].trigHash,
|
||||||
pTrig->name, strlen(pTrig->name)+1, pTrig);
|
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);
|
pTab = sqlite3LocateTable(pParse,pTrig->table,db->aDb[pTrig->iTabDb].zName);
|
||||||
assert( pTab!=0 );
|
assert( pTab!=0 );
|
||||||
pTrig->pNext = pTab->pTrigger;
|
pTrig->pNext = pTab->pTrigger;
|
||||||
@@ -328,18 +337,23 @@ TriggerStep *sqlite3TriggerInsertStep(
|
|||||||
int orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
|
int orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
|
||||||
){
|
){
|
||||||
TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
|
TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
|
||||||
if( pTriggerStep==0 ) return 0;
|
|
||||||
|
|
||||||
assert(pEList == 0 || pSelect == 0);
|
assert(pEList == 0 || pSelect == 0);
|
||||||
assert(pEList != 0 || pSelect != 0);
|
assert(pEList != 0 || pSelect != 0);
|
||||||
|
|
||||||
pTriggerStep->op = TK_INSERT;
|
if( pTriggerStep ){
|
||||||
pTriggerStep->pSelect = pSelect;
|
pTriggerStep->op = TK_INSERT;
|
||||||
pTriggerStep->target = *pTableName;
|
pTriggerStep->pSelect = pSelect;
|
||||||
pTriggerStep->pIdList = pColumn;
|
pTriggerStep->target = *pTableName;
|
||||||
pTriggerStep->pExprList = pEList;
|
pTriggerStep->pIdList = pColumn;
|
||||||
pTriggerStep->orconf = orconf;
|
pTriggerStep->pExprList = pEList;
|
||||||
sqlitePersistTriggerStep(pTriggerStep);
|
pTriggerStep->orconf = orconf;
|
||||||
|
sqlitePersistTriggerStep(pTriggerStep);
|
||||||
|
}else{
|
||||||
|
sqlite3IdListDelete(pColumn);
|
||||||
|
sqlite3ExprListDelete(pEList);
|
||||||
|
sqlite3SelectDup(pSelect);
|
||||||
|
}
|
||||||
|
|
||||||
return pTriggerStep;
|
return pTriggerStep;
|
||||||
}
|
}
|
||||||
|
@@ -271,7 +271,12 @@ void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
|
|||||||
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
||||||
Op *pOp;
|
Op *pOp;
|
||||||
assert( p->magic==VDBE_MAGIC_INIT );
|
assert( p->magic==VDBE_MAGIC_INIT );
|
||||||
if( p==0 || p->aOp==0 ) return;
|
if( p==0 || p->aOp==0 ){
|
||||||
|
if( n==P3_DYNAMIC || n==P3_KEYINFO_HANDOFF ){
|
||||||
|
sqliteFree(zP3);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if( addr<0 || addr>=p->nOp ){
|
if( addr<0 || addr>=p->nOp ){
|
||||||
addr = p->nOp - 1;
|
addr = p->nOp - 1;
|
||||||
if( addr<0 ) return;
|
if( addr<0 ) return;
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
** so is applicable. Because this module is responsible for selecting
|
** so is applicable. Because this module is responsible for selecting
|
||||||
** indices, you might also think of this module as the "query optimizer".
|
** indices, you might also think of this module as the "query optimizer".
|
||||||
**
|
**
|
||||||
** $Id: where.c,v 1.135 2005/02/22 09:47:18 danielk1977 Exp $
|
** $Id: where.c,v 1.136 2005/03/16 12:15:21 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -645,7 +645,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
*/
|
*/
|
||||||
pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
|
pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
|
||||||
if( sqlite3_malloc_failed ){
|
if( sqlite3_malloc_failed ){
|
||||||
/* sqliteFree(pWInfo); // Leak memory when malloc fails */
|
sqliteFree(pWInfo); /* Avoid leaking memory when malloc fails */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pWInfo->pParse = pParse;
|
pWInfo->pParse = pParse;
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file runs all tests.
|
# This file runs all tests.
|
||||||
#
|
#
|
||||||
# $Id: memleak.test,v 1.8 2005/01/17 07:53:44 danielk1977 Exp $
|
# $Id: memleak.test,v 1.9 2005/03/16 12:15:22 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -35,7 +35,6 @@ set LeakList {}
|
|||||||
set EXCLUDE {
|
set EXCLUDE {
|
||||||
all.test
|
all.test
|
||||||
quick.test
|
quick.test
|
||||||
malloc.test
|
|
||||||
misuse.test
|
misuse.test
|
||||||
memleak.test
|
memleak.test
|
||||||
btree2.test
|
btree2.test
|
||||||
|
Reference in New Issue
Block a user