mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-06 15:49:35 +03:00
Malloc for space to hold the Parse object in sqlite3_prepare() and friends.
Or, if compiled with SQLITE_USE_ALLOCA, obtain space for the object from alloca(). (CVS 6702) FossilOrigin-Name: c7c0c58e472cd8277b2ad58bb60834190bace4fa
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Added\sassert\sto\sverify\swinMutex\ssystem\sis\sinited\sbefore\s"static"\smutexes\sare\sused.\s(CVS\s6701)
|
C Malloc\sfor\sspace\sto\shold\sthe\sParse\sobject\sin\ssqlite3_prepare()\sand\sfriends.\nOr,\sif\scompiled\swith\sSQLITE_USE_ALLOCA,\sobtain\sspace\sfor\sthe\sobject\sfrom\nalloca().\s(CVS\s6702)
|
||||||
D 2009-06-01T17:10:22
|
D 2009-06-01T18:18:21
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
|
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -153,7 +153,7 @@ F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d
|
|||||||
F src/pcache.h 9b927ccc5a538e31b4c3bc7eec4f976db42a1324
|
F src/pcache.h 9b927ccc5a538e31b4c3bc7eec4f976db42a1324
|
||||||
F src/pcache1.c bed75f157283e7c666f323df0c874c6a2515f76e
|
F src/pcache1.c bed75f157283e7c666f323df0c874c6a2515f76e
|
||||||
F src/pragma.c d4a6fd74fd1dba0f22c8930791f7fbbe80d2ef26
|
F src/pragma.c d4a6fd74fd1dba0f22c8930791f7fbbe80d2ef26
|
||||||
F src/prepare.c f46d1a029760edee5447e27164fb3ae10e2a6839
|
F src/prepare.c 706efe9fb08b2f01c14c8077dce8ab8450c47cfb
|
||||||
F src/printf.c 3f4dca207a88258d37af5a7a03e800a825fe6456
|
F src/printf.c 3f4dca207a88258d37af5a7a03e800a825fe6456
|
||||||
F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
|
F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
|
||||||
F src/resolve.c f86d3490cf93a12f8a451720defc622cbc79873a
|
F src/resolve.c f86d3490cf93a12f8a451720defc622cbc79873a
|
||||||
@@ -162,7 +162,7 @@ F src/select.c 2d97084a176a63eabce2d043eb4fbb13c46d6e9f
|
|||||||
F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb
|
F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb
|
||||||
F src/sqlite.h.in 79210c4d8905cfb4b038486dde5f36fabb796a86
|
F src/sqlite.h.in 79210c4d8905cfb4b038486dde5f36fabb796a86
|
||||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||||
F src/sqliteInt.h 9d9e15a343bc56e8fc11217d5095f3c9f0508bed
|
F src/sqliteInt.h 210280ec1b4ecc2627b37a6555943e253e615d65
|
||||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
||||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||||
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
|
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
|
||||||
@@ -731,7 +731,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 4e75897ee177bd24145f9dbfccd41a03c108440f
|
P b126013b5a1d6526810139d19acbec7fd0ab8168
|
||||||
R c9b75933dd204df4863fe45c2a3da85c
|
R 5749ee12901dac70e7e5afa66675a445
|
||||||
U shane
|
U drh
|
||||||
Z 73868adefad3a7d624bd940507eb93ad
|
Z d18ab08e2623638148c802e092f00e62
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
b126013b5a1d6526810139d19acbec7fd0ab8168
|
c7c0c58e472cd8277b2ad58bb60834190bace4fa
|
||||||
102
src/prepare.c
102
src/prepare.c
@@ -13,7 +13,7 @@
|
|||||||
** interface, and routines that contribute to loading the database schema
|
** interface, and routines that contribute to loading the database schema
|
||||||
** from disk.
|
** from disk.
|
||||||
**
|
**
|
||||||
** $Id: prepare.c,v 1.118 2009/05/11 20:53:29 drh Exp $
|
** $Id: prepare.c,v 1.119 2009/06/01 18:18:21 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -520,12 +520,22 @@ static int sqlite3Prepare(
|
|||||||
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
|
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
|
||||||
const char **pzTail /* OUT: End of parsed string */
|
const char **pzTail /* OUT: End of parsed string */
|
||||||
){
|
){
|
||||||
Parse sParse;
|
Parse *pParse; /* Parsing context */
|
||||||
char *zErrMsg = 0;
|
char *zErrMsg = 0; /* Error message */
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK; /* Result code */
|
||||||
int i;
|
int i; /* Loop counter */
|
||||||
|
|
||||||
if( sqlite3SafetyOn(db) ) return SQLITE_MISUSE;
|
/* Allocate the parsing context */
|
||||||
|
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
|
||||||
|
if( pParse==0 ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
goto end_prepare;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sqlite3SafetyOn(db) ){
|
||||||
|
rc = SQLITE_MISUSE;
|
||||||
|
goto end_prepare;
|
||||||
|
}
|
||||||
assert( ppStmt && *ppStmt==0 );
|
assert( ppStmt && *ppStmt==0 );
|
||||||
assert( !db->mallocFailed );
|
assert( !db->mallocFailed );
|
||||||
assert( sqlite3_mutex_held(db->mutex) );
|
assert( sqlite3_mutex_held(db->mutex) );
|
||||||
@@ -563,68 +573,71 @@ static int sqlite3Prepare(
|
|||||||
sqlite3Error(db, rc, "database schema is locked: %s", zDb);
|
sqlite3Error(db, rc, "database schema is locked: %s", zDb);
|
||||||
(void)sqlite3SafetyOff(db);
|
(void)sqlite3SafetyOff(db);
|
||||||
testcase( db->flags & SQLITE_ReadUncommitted );
|
testcase( db->flags & SQLITE_ReadUncommitted );
|
||||||
return sqlite3ApiExit(db, rc);
|
goto end_prepare;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&sParse, 0, sizeof(sParse));
|
|
||||||
sParse.db = db;
|
pParse->db = db;
|
||||||
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
|
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
|
||||||
char *zSqlCopy;
|
char *zSqlCopy;
|
||||||
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
|
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
|
||||||
if( nBytes>mxLen ){
|
if( nBytes>mxLen ){
|
||||||
sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
|
sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
|
||||||
(void)sqlite3SafetyOff(db);
|
(void)sqlite3SafetyOff(db);
|
||||||
return sqlite3ApiExit(db, SQLITE_TOOBIG);
|
rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
|
||||||
|
goto end_prepare;
|
||||||
}
|
}
|
||||||
zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
|
zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
|
||||||
if( zSqlCopy ){
|
if( zSqlCopy ){
|
||||||
sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
|
sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
|
||||||
sqlite3DbFree(db, zSqlCopy);
|
sqlite3DbFree(db, zSqlCopy);
|
||||||
sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
|
pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
|
||||||
}else{
|
}else{
|
||||||
sParse.zTail = &zSql[nBytes];
|
pParse->zTail = &zSql[nBytes];
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
sqlite3RunParser(&sParse, zSql, &zErrMsg);
|
sqlite3RunParser(pParse, zSql, &zErrMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( db->mallocFailed ){
|
if( db->mallocFailed ){
|
||||||
sParse.rc = SQLITE_NOMEM;
|
pParse->rc = SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
|
if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
|
||||||
if( sParse.checkSchema && !schemaIsValid(db) ){
|
if( pParse->checkSchema && !schemaIsValid(db) ){
|
||||||
sParse.rc = SQLITE_SCHEMA;
|
pParse->rc = SQLITE_SCHEMA;
|
||||||
}
|
}
|
||||||
if( sParse.rc==SQLITE_SCHEMA ){
|
if( pParse->rc==SQLITE_SCHEMA ){
|
||||||
sqlite3ResetInternalSchema(db, 0);
|
sqlite3ResetInternalSchema(db, 0);
|
||||||
}
|
}
|
||||||
if( db->mallocFailed ){
|
if( db->mallocFailed ){
|
||||||
sParse.rc = SQLITE_NOMEM;
|
pParse->rc = SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
if( pzTail ){
|
if( pzTail ){
|
||||||
*pzTail = sParse.zTail;
|
*pzTail = pParse->zTail;
|
||||||
}
|
}
|
||||||
rc = sParse.rc;
|
rc = pParse->rc;
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_EXPLAIN
|
#ifndef SQLITE_OMIT_EXPLAIN
|
||||||
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
|
if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
|
||||||
if( sParse.explain==2 ){
|
static const char * const azColName[] = {
|
||||||
sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
|
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", SQLITE_STATIC);
|
"order", "from", "detail"
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", SQLITE_STATIC);
|
};
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", SQLITE_STATIC);
|
int iFirst, mx;
|
||||||
|
if( pParse->explain==2 ){
|
||||||
|
sqlite3VdbeSetNumCols(pParse->pVdbe, 3);
|
||||||
|
iFirst = 8;
|
||||||
|
mx = 11;
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
|
sqlite3VdbeSetNumCols(pParse->pVdbe, 8);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", SQLITE_STATIC);
|
iFirst = 0;
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", SQLITE_STATIC);
|
mx = 8;
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", SQLITE_STATIC);
|
}
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", SQLITE_STATIC);
|
for(i=iFirst; i<mx; i++){
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", SQLITE_STATIC);
|
sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 5, COLNAME_NAME, "p4", SQLITE_STATIC);
|
azColName[i], SQLITE_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 6, COLNAME_NAME, "p5", SQLITE_STATIC);
|
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 7, COLNAME_NAME, "comment", SQLITE_STATIC);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -635,14 +648,14 @@ static int sqlite3Prepare(
|
|||||||
|
|
||||||
assert( db->init.busy==0 || saveSqlFlag==0 );
|
assert( db->init.busy==0 || saveSqlFlag==0 );
|
||||||
if( db->init.busy==0 ){
|
if( db->init.busy==0 ){
|
||||||
Vdbe *pVdbe = sParse.pVdbe;
|
Vdbe *pVdbe = pParse->pVdbe;
|
||||||
sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag);
|
sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
|
||||||
}
|
}
|
||||||
if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
|
if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
|
||||||
sqlite3VdbeFinalize(sParse.pVdbe);
|
sqlite3VdbeFinalize(pParse->pVdbe);
|
||||||
assert(!(*ppStmt));
|
assert(!(*ppStmt));
|
||||||
}else{
|
}else{
|
||||||
*ppStmt = (sqlite3_stmt*)sParse.pVdbe;
|
*ppStmt = (sqlite3_stmt*)pParse->pVdbe;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( zErrMsg ){
|
if( zErrMsg ){
|
||||||
@@ -652,6 +665,9 @@ static int sqlite3Prepare(
|
|||||||
sqlite3Error(db, rc, 0);
|
sqlite3Error(db, rc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end_prepare:
|
||||||
|
|
||||||
|
sqlite3StackFree(db, pParse);
|
||||||
rc = sqlite3ApiExit(db, rc);
|
rc = sqlite3ApiExit(db, rc);
|
||||||
assert( (rc&db->errMask)==rc );
|
assert( (rc&db->errMask)==rc );
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.879 2009/05/30 14:16:32 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.880 2009/06/01 18:18:21 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -475,6 +475,7 @@ extern const int sqlite3one;
|
|||||||
*/
|
*/
|
||||||
#define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
|
#define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** An instance of the following structure is used to store the busy-handler
|
** An instance of the following structure is used to store the busy-handler
|
||||||
** callback for a given sqlite handle.
|
** callback for a given sqlite handle.
|
||||||
@@ -2360,6 +2361,24 @@ void sqlite3MemSetDefault(void);
|
|||||||
void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
|
void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
|
||||||
int sqlite3MemoryAlarm(void (*)(void*, sqlite3_int64, int), void*, sqlite3_int64);
|
int sqlite3MemoryAlarm(void (*)(void*, sqlite3_int64, int), void*, sqlite3_int64);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** On systems with ample stack space and that support alloca(), make
|
||||||
|
** use of alloca() to obtain space for large automatic objects. By default,
|
||||||
|
** obtain space from malloc().
|
||||||
|
**
|
||||||
|
** The alloca() routine never returns NULL. This will cause code paths
|
||||||
|
** that deal with sqlite3StackAlloc() failures to be unreachable.
|
||||||
|
*/
|
||||||
|
#ifdef SQLITE_USE_ALLOCA
|
||||||
|
# define sqlite3StackAllocRaw(D,N) alloca(N)
|
||||||
|
# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N)
|
||||||
|
# define sqlite3StackFree(D,P)
|
||||||
|
#else
|
||||||
|
# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N)
|
||||||
|
# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N)
|
||||||
|
# define sqlite3StackFree(D,P) sqlite3DbFree(D,P)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_MEMSYS3
|
#ifdef SQLITE_ENABLE_MEMSYS3
|
||||||
const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
|
const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user