aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2009-06-02 21:31:38 +0000
committerdrh <drh@noemail.net>2009-06-02 21:31:38 +0000
commite98c9049a0a56ea8c3a704a986298f1dc5a9af2f (patch)
treec2050cc77cfe5f1db7bd7619d17453b97a025cba /src
parentc54a617e1ff59a717960a876977b7c56f2276715 (diff)
downloadsqlite-e98c9049a0a56ea8c3a704a986298f1dc5a9af2f.tar.gz
sqlite-e98c9049a0a56ea8c3a704a986298f1dc5a9af2f.zip
Further reductions in the amount of stack space required. (CVS 6707)
FossilOrigin-Name: 04bad9eb6dd8bf7cafc9f3918b676e95d5b1c984
Diffstat (limited to 'src')
-rw-r--r--src/backup.c25
-rw-r--r--src/bitvec.c41
-rw-r--r--src/pager.c5
-rw-r--r--src/sqliteInt.h4
-rw-r--r--src/vtab.c60
5 files changed, 80 insertions, 55 deletions
diff --git a/src/backup.c b/src/backup.c
index e0ab5d882..a1cb85503 100644
--- a/src/backup.c
+++ b/src/backup.c
@@ -12,7 +12,7 @@
** This file contains the implementation of the sqlite3_backup_XXX()
** API functions and the related features.
**
-** $Id: backup.c,v 1.15 2009/05/14 19:26:51 drh Exp $
+** $Id: backup.c,v 1.16 2009/06/02 21:31:39 drh Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"
@@ -91,15 +91,24 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
int i = sqlite3FindDbName(pDb, zDb);
if( i==1 ){
- Parse sParse;
- memset(&sParse, 0, sizeof(sParse));
- sParse.db = pDb;
- if( sqlite3OpenTempDatabase(&sParse) ){
- sqlite3ErrorClear(&sParse);
- sqlite3Error(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
+ Parse *pParse;
+ int rc = 0;
+ pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
+ if( pParse==0 ){
+ sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory");
+ rc = SQLITE_NOMEM;
+ }else{
+ pParse->db = pDb;
+ if( sqlite3OpenTempDatabase(pParse) ){
+ sqlite3ErrorClear(pParse);
+ sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
+ rc = SQLITE_ERROR;
+ }
+ sqlite3StackFree(pErrorDb, pParse);
+ }
+ if( rc ){
return 0;
}
- assert( sParse.zErrMsg==0 );
}
if( i<0 ){
diff --git a/src/bitvec.c b/src/bitvec.c
index b6420a7f2..616c2adc5 100644
--- a/src/bitvec.c
+++ b/src/bitvec.c
@@ -34,7 +34,7 @@
** start of a transaction, and is thus usually less than a few thousand,
** but can be as large as 2 billion for a really big database.
**
-** @(#) $Id: bitvec.c,v 1.14 2009/04/01 23:49:04 drh Exp $
+** @(#) $Id: bitvec.c,v 1.15 2009/06/02 21:31:39 drh Exp $
*/
#include "sqliteInt.h"
@@ -209,15 +209,20 @@ bitvec_set_rehash:
if( p->nSet>=BITVEC_MXHASH ){
unsigned int j;
int rc;
- u32 aiValues[BITVEC_NINT];
- memcpy(aiValues, p->u.aHash, sizeof(aiValues));
- memset(p->u.apSub, 0, sizeof(aiValues));
- p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
- rc = sqlite3BitvecSet(p, i);
- for(j=0; j<BITVEC_NINT; j++){
- if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
+ u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
+ if( aiValues==0 ){
+ return SQLITE_NOMEM;
+ }else{
+ memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
+ memset(p->u.apSub, 0, sizeof(p->u.apSub));
+ p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
+ rc = sqlite3BitvecSet(p, i);
+ for(j=0; j<BITVEC_NINT; j++){
+ if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
+ }
+ sqlite3StackFree(0, aiValues);
+ return rc;
}
- return rc;
}
bitvec_set_end:
p->nSet++;
@@ -227,8 +232,11 @@ bitvec_set_end:
/*
** Clear the i-th bit.
+**
+** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
+** that BitvecClear can use to rebuilt its hash table.
*/
-void sqlite3BitvecClear(Bitvec *p, u32 i){
+void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
assert( p!=0 );
assert( i>0 );
i--;
@@ -244,9 +252,9 @@ void sqlite3BitvecClear(Bitvec *p, u32 i){
p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
}else{
unsigned int j;
- u32 aiValues[BITVEC_NINT];
- memcpy(aiValues, p->u.aHash, sizeof(aiValues));
- memset(p->u.aHash, 0, sizeof(aiValues));
+ u32 *aiValues = pBuf;
+ memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
+ memset(p->u.aHash, 0, sizeof(p->u.aHash));
p->nSet = 0;
for(j=0; j<BITVEC_NINT; j++){
if( aiValues[j] && aiValues[j]!=(i+1) ){
@@ -330,12 +338,14 @@ int sqlite3BitvecBuiltinTest(int sz, int *aOp){
unsigned char *pV = 0;
int rc = -1;
int i, nx, pc, op;
+ void *pTmpSpace;
/* Allocate the Bitvec to be tested and a linear array of
** bits to act as the reference */
pBitvec = sqlite3BitvecCreate( sz );
pV = sqlite3_malloc( (sz+7)/8 + 1 );
- if( pBitvec==0 || pV==0 ) goto bitvec_end;
+ pTmpSpace = sqlite3_malloc(BITVEC_SZ);
+ if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
memset(pV, 0, (sz+7)/8 + 1);
/* Run the program */
@@ -368,7 +378,7 @@ int sqlite3BitvecBuiltinTest(int sz, int *aOp){
}
}else{
CLEARBIT(pV, (i+1));
- sqlite3BitvecClear(pBitvec, i+1);
+ sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
}
}
@@ -389,6 +399,7 @@ int sqlite3BitvecBuiltinTest(int sz, int *aOp){
/* Free allocated structure */
bitvec_end:
+ sqlite3_free(pTmpSpace);
sqlite3_free(pV);
sqlite3BitvecDestroy(pBitvec);
return rc;
diff --git a/src/pager.c b/src/pager.c
index 274949043..16cc70c81 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.590 2009/05/29 11:57:38 drh Exp $
+** @(#) $Id: pager.c,v 1.591 2009/06/02 21:31:39 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@@ -5166,7 +5166,8 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
if( rc!=SQLITE_OK ){
if( pPager->pInJournal && needSyncPgno<=pPager->dbOrigSize ){
- sqlite3BitvecClear(pPager->pInJournal, needSyncPgno);
+ assert( pPager->pTmpSpace!=0 );
+ sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
}
return rc;
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index d6b150630..eaf35872f 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.880 2009/06/01 18:18:21 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.881 2009/06/02 21:31:39 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -2455,7 +2455,7 @@ void sqlite3EndTable(Parse*,Token*,Token*,Select*);
Bitvec *sqlite3BitvecCreate(u32);
int sqlite3BitvecTest(Bitvec*, u32);
int sqlite3BitvecSet(Bitvec*, u32);
-void sqlite3BitvecClear(Bitvec*, u32);
+void sqlite3BitvecClear(Bitvec*, u32, void*);
void sqlite3BitvecDestroy(Bitvec*);
u32 sqlite3BitvecSize(Bitvec*);
int sqlite3BitvecBuiltinTest(int,int*);
diff --git a/src/vtab.c b/src/vtab.c
index 3c7316c02..10a168162 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to help implement virtual tables.
**
-** $Id: vtab.c,v 1.89 2009/05/20 20:10:47 drh Exp $
+** $Id: vtab.c,v 1.90 2009/06/02 21:31:39 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"
@@ -550,7 +550,7 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
** virtual table module.
*/
int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
- Parse sParse;
+ Parse *pParse;
int rc = SQLITE_OK;
Table *pTab;
@@ -565,33 +565,37 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
}
assert((pTab->tabFlags & TF_Virtual)!=0 && pTab->nCol==0 && pTab->aCol==0);
- memset(&sParse, 0, sizeof(Parse));
- sParse.declareVtab = 1;
- sParse.db = db;
-
- if(
- SQLITE_OK == sqlite3RunParser(&sParse, zCreateTable, &zErr) &&
- sParse.pNewTable &&
- !sParse.pNewTable->pSelect &&
- (sParse.pNewTable->tabFlags & TF_Virtual)==0
- ){
- pTab->aCol = sParse.pNewTable->aCol;
- pTab->nCol = sParse.pNewTable->nCol;
- sParse.pNewTable->nCol = 0;
- sParse.pNewTable->aCol = 0;
- db->pVTab = 0;
- } else {
- sqlite3Error(db, SQLITE_ERROR, zErr);
- sqlite3DbFree(db, zErr);
- rc = SQLITE_ERROR;
- }
- sParse.declareVtab = 0;
-
- if( sParse.pVdbe ){
- sqlite3VdbeFinalize(sParse.pVdbe);
+ pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
+ if( pParse==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ pParse->declareVtab = 1;
+ pParse->db = db;
+
+ if(
+ SQLITE_OK == sqlite3RunParser(pParse, zCreateTable, &zErr) &&
+ pParse->pNewTable &&
+ !pParse->pNewTable->pSelect &&
+ (pParse->pNewTable->tabFlags & TF_Virtual)==0
+ ){
+ pTab->aCol = pParse->pNewTable->aCol;
+ pTab->nCol = pParse->pNewTable->nCol;
+ pParse->pNewTable->nCol = 0;
+ pParse->pNewTable->aCol = 0;
+ db->pVTab = 0;
+ } else {
+ sqlite3Error(db, SQLITE_ERROR, zErr);
+ sqlite3DbFree(db, zErr);
+ rc = SQLITE_ERROR;
+ }
+ pParse->declareVtab = 0;
+
+ if( pParse->pVdbe ){
+ sqlite3VdbeFinalize(pParse->pVdbe);
+ }
+ sqlite3DeleteTable(pParse->pNewTable);
+ sqlite3StackFree(db, pParse);
}
- sqlite3DeleteTable(sParse.pNewTable);
- sParse.pNewTable = 0;
assert( (rc&0xff)==rc );
rc = sqlite3ApiExit(db, rc);