Pull the latest trunk changes into the wal-readonly branch.

FossilOrigin-Name: 0b63b71357a65e26ecd3f3bb34a5f14feee322f4
This commit is contained in:
drh 2011-06-01 19:44:57 +00:00
commit f167694f9a
13 changed files with 207 additions and 210 deletions

View File

@ -1,5 +1,5 @@
C Merge\sthe\slatest\strunk\schanges\sinto\sthe\swal-readonly\sbranch.
D 2011-05-31T17:08:32.975
C Pull\sthe\slatest\strunk\schanges\sinto\sthe\swal-readonly\sbranch.
D 2011-06-01T19:44:57.308
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -125,13 +125,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 0d3b39dcb79565c053e35fc12713f12d8a74d6a9
F src/btree.h d796dc4030b3cce7f5a0cc4f2f986d2befa6b8ac
F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3
F src/build.c 0132bc6631fa617a1d28ef805921f6dbac18a514
F src/build.c c10ab9e2c77ade99dee23554787f8acfc0c231fc
F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4
F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b
F src/delete.c cecc926c70783452f3e8eb452c728291ce1a0b21
F src/expr.c e3cf0957c6b8faaaf7386a3bc69e53c0dc9705be
F src/expr.c ab46ab0f0c44979a8164ca31728d7d10ae5e8106
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c a43ba8a005fb5efd1deeee06853e3a6120d46a91
F src/func.c b9117e40975245b8504cf3625d7e321d8d4b63dc
@ -179,9 +179,9 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff
F src/shell.c decd04236a7ef26be5ef46d4ea963044bfad9a48
F src/sqlite.h.in 55fe75ae0d2ee71c33283bae647443c8ec8400be
F src/sqlite.h.in dbe88418628302c0a93671a216346acb5746211a
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
F src/sqliteInt.h 8936583efbbc5820e9b01befa6e76947a2be8f52
F src/sqliteInt.h 219b21e80f46eef7cc7bb7477c12de61d00f5607
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@ -230,18 +230,18 @@ F src/test_vfs.c e7855568dfa1e0ba73668d273b65605d9f8b77e8
F src/test_vfstrace.c 0b884e06094a746da729119a2cabdc7aa790063d
F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080
F src/tokenize.c 7b0c9281b2368dc69135e7a50bd271de9af1b467
F src/trigger.c 144cc18bb701f3286484aae4292a9531f09278c8
F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f
F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60
F src/util.c 0f33bbbdfcc4a2d8cf20c3b2a16ffc3b57c58a70
F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e
F src/vdbe.c 103827f560cdc48b1d455ce4d4b3573dd88f9ab4
F src/vdbe.h 8a675fefdf7119441fe817c800a9a52440c2e797
F src/vdbeInt.h fe8f58d305e629fff02f61f655aca1d299f1f6ae
F src/vdbeapi.c e0e2672e0a96ae3f8575c8ecd02912a3e8a554a1
F src/vdbeaux.c 99900868d18618a07ffaf780ecc41fd807834bde
F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562
F src/vdbe.c 2ec37637fa70ab0c694d8327ee5dcedbc0621524
F src/vdbe.h d9c6123384189dc37d27beac1bf44688aa75b6cb
F src/vdbeInt.h ad84226cc0adcb1185c22b70696b235a1678bb45
F src/vdbeapi.c 0eeadc75e44a30efd996d6af6e7c5a2488e35be8
F src/vdbeaux.c 0505dc4f7ff3cf35e219fe0a20ab798a42772b8b
F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3
F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b
F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114
F src/vtab.c 9ba8c7fdb7d39260c033a402f6032d3e7bc5d336
@ -939,7 +939,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 6a2ea52e6c09a570428161090c2f087c66f714ec a0ae314c7f41d0146a9ee1adc576cd977219a378
R 2d882c761e53216861edc4b651b9e13f
P 2c6b5a28e3f6b7cb96b944d0a254f3707885f1ce e704e8690ae35decc9769a45cf8d519ccad8b79d
R 5f4edf2ff77d011b562e3dc234f8f21d
U drh
Z 136bd350bac5191ea5a92cebd8db2492
Z 99212444a62258034d706d358ee0a50e

View File

@ -1 +1 @@
2c6b5a28e3f6b7cb96b944d0a254f3707885f1ce
0b63b71357a65e26ecd3f3bb34a5f14feee322f4

View File

@ -200,9 +200,7 @@ void sqlite3FinishCoding(Parse *pParse){
/* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */
if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem,
pParse->nTab, pParse->nMaxArg, pParse->explain,
pParse->isMultiWrite && pParse->mayAbort);
sqlite3VdbeMakeReady(v, pParse);
pParse->rc = SQLITE_DONE;
pParse->colNamesSet = 0;
}else{

View File

@ -555,53 +555,53 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
/* Wildcard of the form "?". Assign the next variable number */
assert( z[0]=='?' );
pExpr->iColumn = (ynVar)(++pParse->nVar);
}else if( z[0]=='?' ){
/* Wildcard of the form "?nnn". Convert "nnn" to an integer and
** use it as the variable number */
i64 i;
int bOk = 0==sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8);
pExpr->iColumn = (ynVar)i;
testcase( i==0 );
testcase( i==1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
}
if( i>pParse->nVar ){
pParse->nVar = (int)i;
}
}else{
/* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
** number as the prior appearance of the same name, or if the name
** has never appeared before, reuse the same variable number
*/
int i;
u32 n;
n = sqlite3Strlen30(z);
for(i=0; i<pParse->nVarExpr; i++){
Expr *pE = pParse->apVarExpr[i];
assert( pE!=0 );
if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){
pExpr->iColumn = pE->iColumn;
break;
ynVar x = 0;
u32 n = sqlite3Strlen30(z);
if( z[0]=='?' ){
/* Wildcard of the form "?nnn". Convert "nnn" to an integer and
** use it as the variable number */
i64 i;
int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
pExpr->iColumn = x = (ynVar)i;
testcase( i==0 );
testcase( i==1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
x = 0;
}
if( i>pParse->nVar ){
pParse->nVar = (int)i;
}
}else{
/* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
** number as the prior appearance of the same name, or if the name
** has never appeared before, reuse the same variable number
*/
ynVar i;
for(i=0; i<pParse->nzVar; i++){
if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){
pExpr->iColumn = x = (ynVar)i+1;
break;
}
}
if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
}
if( i>=pParse->nVarExpr ){
pExpr->iColumn = (ynVar)(++pParse->nVar);
if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
pParse->apVarExpr =
sqlite3DbReallocOrFree(
db,
pParse->apVarExpr,
pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0])
);
if( x>0 ){
if( x>pParse->nzVar ){
char **a;
a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
if( a==0 ) return; /* Error reported through db->mallocFailed */
pParse->azVar = a;
memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
pParse->nzVar = x;
}
if( !db->mallocFailed ){
assert( pParse->apVarExpr!=0 );
pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
if( z[0]!='?' || pParse->azVar[x-1]==0 ){
sqlite3DbFree(db, pParse->azVar[x-1]);
pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
}
}
}
@ -2345,7 +2345,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
assert( pExpr->u.zToken[0]!=0 );
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
if( pExpr->u.zToken[1]!=0 ){
sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, P4_TRANSIENT);
assert( pExpr->u.zToken[0]=='?'
|| strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 );
sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC);
}
break;
}

View File

@ -3109,8 +3109,6 @@ int sqlite3_bind_parameter_count(sqlite3_stmt*);
** is included as part of the name.)^
** ^Parameters of the form "?" without a following integer have no name
** and are referred to as "nameless" or "anonymous parameters".
** ^Any parameter that is optimized out of the prepared statement by the
** query planner becomes a nameless or anonymous parameter.
**
** ^The first host parameter has an index of 1, not 0.
**

View File

@ -2230,9 +2230,8 @@ struct Parse {
** each recursion */
int nVar; /* Number of '?' variables seen in the SQL so far */
int nVarExpr; /* Number of used slots in apVarExpr[] */
int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */
Expr **apVarExpr; /* Pointers to :aaa and $aaaa wildcard expressions */
int nzVar; /* Number of available slots in azVar[] */
char **azVar; /* Pointers to names of parameters */
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
int nAlias; /* Number of aliased result set columns */
int nAliasAlloc; /* Number of allocated slots for aAlias[] */

View File

@ -412,9 +412,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
assert( pParse->pNewTable==0 );
assert( pParse->pNewTrigger==0 );
assert( pParse->nVar==0 );
assert( pParse->nVarExpr==0 );
assert( pParse->nVarExprAlloc==0 );
assert( pParse->apVarExpr==0 );
assert( pParse->nzVar==0 );
assert( pParse->azVar==0 );
enableLookaside = db->lookaside.bEnabled;
if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
while( !db->mallocFailed && zSql[i]!=0 ){
@ -508,7 +507,8 @@ abort_parse:
}
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
sqlite3DbFree(db, pParse->apVarExpr);
for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
sqlite3DbFree(db, pParse->azVar);
sqlite3DbFree(db, pParse->aAlias);
while( pParse->pAinc ){
AutoincInfo *p = pParse->pAinc;

View File

@ -988,6 +988,7 @@ case OP_Variable: { /* out2-prerelease */
Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
pVar = &p->aVar[pOp->p1 - 1];
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;

View File

@ -185,7 +185,7 @@ int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeRunOnlyOnce(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);
void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*);
void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int);
void sqlite3VdbeMakeReady(Vdbe*,Parse*);
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
@ -194,6 +194,7 @@ int sqlite3VdbeCurrentAddr(Vdbe*);
void sqlite3VdbeTrace(Vdbe*,FILE*);
#endif
void sqlite3VdbeResetStepResult(Vdbe*);
void sqlite3VdbeRewind(Vdbe*);
int sqlite3VdbeReset(Vdbe*);
void sqlite3VdbeSetNumCols(Vdbe*,int);
int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));

View File

@ -287,11 +287,11 @@ struct Vdbe {
Mem *aVar; /* Values for the OP_Variable opcode. */
char **azVar; /* Name of variables */
ynVar nVar; /* Number of entries in aVar[] */
ynVar nzVar; /* Number of entries in azVar[] */
u32 cacheCtr; /* VdbeCursor row cache generation counter */
int pc; /* The program counter */
int rc; /* Value to return */
u8 errorAction; /* Recovery action to do in case of an error */
u8 okVar; /* True if azVar[] has been initialized */
u8 explain; /* True if EXPLAIN present on SQL command */
u8 changeCntOn; /* True to update the change-counter */
u8 expired; /* True if the VM needs to be recompiled */

View File

@ -102,7 +102,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt){
Vdbe *v = (Vdbe*)pStmt;
sqlite3_mutex_enter(v->db->mutex);
rc = sqlite3VdbeReset(v);
sqlite3VdbeMakeReady(v, -1, 0, 0, 0, 0, 0);
sqlite3VdbeRewind(v);
assert( (rc & (v->db->errMask))==rc );
rc = sqlite3ApiExit(v->db, rc);
sqlite3_mutex_leave(v->db->mutex);
@ -1167,32 +1167,6 @@ int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
return p ? p->nVar : 0;
}
/*
** Create a mapping from variable numbers to variable names
** in the Vdbe.azVar[] array, if such a mapping does not already
** exist.
*/
static void createVarMap(Vdbe *p){
if( !p->okVar ){
int j;
Op *pOp;
sqlite3_mutex_enter(p->db->mutex);
/* The race condition here is harmless. If two threads call this
** routine on the same Vdbe at the same time, they both might end
** up initializing the Vdbe.azVar[] array. That is a little extra
** work but it results in the same answer.
*/
for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){
if( pOp->opcode==OP_Variable ){
assert( pOp->p1>0 && pOp->p1<=p->nVar );
p->azVar[pOp->p1-1] = pOp->p4.z;
}
}
p->okVar = 1;
sqlite3_mutex_leave(p->db->mutex);
}
}
/*
** Return the name of a wildcard parameter. Return NULL if the index
** is out of range or if the wildcard is unnamed.
@ -1201,10 +1175,9 @@ static void createVarMap(Vdbe *p){
*/
const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
Vdbe *p = (Vdbe*)pStmt;
if( p==0 || i<1 || i>p->nVar ){
if( p==0 || i<1 || i>p->nzVar ){
return 0;
}
createVarMap(p);
return p->azVar[i-1];
}
@ -1218,9 +1191,8 @@ int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
if( p==0 ){
return 0;
}
createVarMap(p);
if( zName ){
for(i=0; i<p->nVar; i++){
for(i=0; i<p->nzVar; i++){
const char *z = p->azVar[i];
if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){
return i+1;

View File

@ -1391,34 +1391,13 @@ static void *allocSpace(
}
/*
** Prepare a virtual machine for execution. This involves things such
** as allocating stack space and initializing the program counter.
** After the VDBE has be prepped, it can be executed by one or more
** calls to sqlite3VdbeExec().
**
** This is the only way to move a VDBE from VDBE_MAGIC_INIT to
** VDBE_MAGIC_RUN.
**
** This function may be called more than once on a single virtual machine.
** The first call is made while compiling the SQL statement. Subsequent
** calls are made as part of the process of resetting a statement to be
** re-executed (from a call to sqlite3_reset()). The nVar, nMem, nCursor
** and isExplain parameters are only passed correct values the first time
** the function is called. On subsequent calls, from sqlite3_reset(), nVar
** is passed -1 and nMem, nCursor and isExplain are all passed zero.
** Rewind the VDBE back to the beginning in preparation for
** running it.
*/
void sqlite3VdbeMakeReady(
Vdbe *p, /* The VDBE */
int nVar, /* Number of '?' see in the SQL statement */
int nMem, /* Number of memory cells to allocate */
int nCursor, /* Number of cursors to allocate */
int nArg, /* Maximum number of args in SubPrograms */
int isExplain, /* True if the EXPLAIN keywords is present */
int usesStmtJournal /* True to set Vdbe.usesStmtJournal */
){
int n;
sqlite3 *db = p->db;
void sqlite3VdbeRewind(Vdbe *p){
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
int i;
#endif
assert( p!=0 );
assert( p->magic==VDBE_MAGIC_INIT );
@ -1429,6 +1408,71 @@ void sqlite3VdbeMakeReady(
/* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
p->magic = VDBE_MAGIC_RUN;
#ifdef SQLITE_DEBUG
for(i=1; i<p->nMem; i++){
assert( p->aMem[i].db==p->db );
}
#endif
p->pc = -1;
p->rc = SQLITE_OK;
p->errorAction = OE_Abort;
p->magic = VDBE_MAGIC_RUN;
p->nChange = 0;
p->cacheCtr = 1;
p->minWriteFileFormat = 255;
p->iStatement = 0;
p->nFkConstraint = 0;
#ifdef VDBE_PROFILE
for(i=0; i<p->nOp; i++){
p->aOp[i].cnt = 0;
p->aOp[i].cycles = 0;
}
#endif
}
/*
** Prepare a virtual machine for execution for the first time after
** creating the virtual machine. This involves things such
** as allocating stack space and initializing the program counter.
** After the VDBE has be prepped, it can be executed by one or more
** calls to sqlite3VdbeExec().
**
** This function may be called exact once on a each virtual machine.
** After this routine is called the VM has been "packaged" and is ready
** to run. After this routine is called, futher calls to
** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects
** the Vdbe from the Parse object that helped generate it so that the
** the Vdbe becomes an independent entity and the Parse object can be
** destroyed.
**
** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back
** to its initial state after it has been run.
*/
void sqlite3VdbeMakeReady(
Vdbe *p, /* The VDBE */
Parse *pParse /* Parsing context */
){
sqlite3 *db; /* The database connection */
int nVar; /* Number of parameters */
int nMem; /* Number of VM memory registers */
int nCursor; /* Number of cursors required */
int nArg; /* Number of arguments in subprograms */
int n; /* Loop counter */
u8 *zCsr; /* Memory available for allocation */
u8 *zEnd; /* First byte past allocated memory */
int nByte; /* How much extra memory is needed */
assert( p!=0 );
assert( p->nOp>0 );
assert( pParse!=0 );
assert( p->magic==VDBE_MAGIC_INIT );
db = p->db;
assert( db->mallocFailed==0 );
nVar = pParse->nVar;
nMem = pParse->nMem;
nCursor = pParse->nTab;
nArg = pParse->nMaxArg;
/* For each cursor required, also allocate a memory cell. Memory
** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
** the vdbe program. Instead they are used to allocate space for
@ -1441,91 +1485,68 @@ void sqlite3VdbeMakeReady(
nMem += nCursor;
/* Allocate space for memory registers, SQL variables, VDBE cursors and
** an array to marshal SQL function arguments in. This is only done the
** first time this function is called for a given VDBE, not when it is
** being called from sqlite3_reset() to reset the virtual machine.
** an array to marshal SQL function arguments in.
*/
if( nVar>=0 && ALWAYS(db->mallocFailed==0) ){
u8 *zCsr = (u8 *)&p->aOp[p->nOp]; /* Memory avaliable for alloation */
u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc]; /* First byte past available mem */
int nByte; /* How much extra memory needed */
zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */
resolveP2Values(p, &nArg);
p->usesStmtJournal = (u8)usesStmtJournal;
if( isExplain && nMem<10 ){
nMem = 10;
resolveP2Values(p, &nArg);
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
if( pParse->explain && nMem<10 ){
nMem = 10;
}
memset(zCsr, 0, zEnd-zCsr);
zCsr += (zCsr - (u8*)0)&7;
assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
/* Memory for registers, parameters, cursor, etc, is allocated in two
** passes. On the first pass, we try to reuse unused space at the
** end of the opcode array. If we are unable to satisfy all memory
** requirements by reusing the opcode array tail, then the second
** pass will fill in the rest using a fresh allocation.
**
** This two-pass approach that reuses as much memory as possible from
** the leftover space at the end of the opcode array can significantly
** reduce the amount of memory held by a prepared statement.
*/
do {
nByte = 0;
p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
&zCsr, zEnd, &nByte);
if( nByte ){
p->pFree = sqlite3DbMallocZero(db, nByte);
}
memset(zCsr, 0, zEnd-zCsr);
zCsr += (zCsr - (u8*)0)&7;
assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
zCsr = p->pFree;
zEnd = &zCsr[nByte];
}while( nByte && !db->mallocFailed );
/* Memory for registers, parameters, cursor, etc, is allocated in two
** passes. On the first pass, we try to reuse unused space at the
** end of the opcode array. If we are unable to satisfy all memory
** requirements by reusing the opcode array tail, then the second
** pass will fill in the rest using a fresh allocation.
**
** This two-pass approach that reuses as much memory as possible from
** the leftover space at the end of the opcode array can significantly
** reduce the amount of memory held by a prepared statement.
*/
do {
nByte = 0;
p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
&zCsr, zEnd, &nByte);
if( nByte ){
p->pFree = sqlite3DbMallocZero(db, nByte);
}
zCsr = p->pFree;
zEnd = &zCsr[nByte];
}while( nByte && !db->mallocFailed );
p->nCursor = (u16)nCursor;
if( p->aVar ){
p->nVar = (ynVar)nVar;
for(n=0; n<nVar; n++){
p->aVar[n].flags = MEM_Null;
p->aVar[n].db = db;
}
}
if( p->aMem ){
p->aMem--; /* aMem[] goes from 1..nMem */
p->nMem = nMem; /* not from 0..nMem-1 */
for(n=1; n<=nMem; n++){
p->aMem[n].flags = MEM_Null;
p->aMem[n].db = db;
}
p->nCursor = (u16)nCursor;
if( p->aVar ){
p->nVar = (ynVar)nVar;
for(n=0; n<nVar; n++){
p->aVar[n].flags = MEM_Null;
p->aVar[n].db = db;
}
}
#ifdef SQLITE_DEBUG
for(n=1; n<p->nMem; n++){
assert( p->aMem[n].db==db );
if( p->azVar ){
p->nzVar = pParse->nzVar;
memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
}
#endif
p->pc = -1;
p->rc = SQLITE_OK;
p->errorAction = OE_Abort;
p->explain |= isExplain;
p->magic = VDBE_MAGIC_RUN;
p->nChange = 0;
p->cacheCtr = 1;
p->minWriteFileFormat = 255;
p->iStatement = 0;
p->nFkConstraint = 0;
#ifdef VDBE_PROFILE
{
int i;
for(i=0; i<p->nOp; i++){
p->aOp[i].cnt = 0;
p->aOp[i].cycles = 0;
if( p->aMem ){
p->aMem--; /* aMem[] goes from 1..nMem */
p->nMem = nMem; /* not from 0..nMem-1 */
for(n=1; n<=nMem; n++){
p->aMem[n].flags = MEM_Null;
p->aMem[n].db = db;
}
}
#endif
p->explain = pParse->explain;
sqlite3VdbeRewind(p);
}
/*
@ -2399,6 +2420,7 @@ void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
*/
void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){
SubProgram *pSub, *pNext;
int i;
assert( p->db==0 || p->db==db );
releaseMemArray(p->aVar, p->nVar);
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
@ -2407,6 +2429,7 @@ void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){
vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
sqlite3DbFree(db, pSub);
}
for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
vdbeFreeOpArray(db, p->aOp, p->nOp);
sqlite3DbFree(db, p->aLabel);
sqlite3DbFree(db, p->aColName);

View File

@ -297,7 +297,10 @@ int sqlite3_blob_open(
sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
sqlite3VdbeChangeP2(v, 7, pTab->nCol);
if( !db->mallocFailed ){
sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0);
pParse->nVar = 1;
pParse->nMem = 1;
pParse->nTab = 1;
sqlite3VdbeMakeReady(v, pParse);
}
}