-C Change\ssome\sassert()\sstatements\sin\svdbe.c\sto\sensure\sthat\sa\smemory\scell\sused\sto\sstore\sa\sVdbeCursor\sobject\sis\snot\salso\sused\sfor\ssome\sother\spurpose.
-D 2013-08-15T16:18:39.664
+C Fix\sa\scrash\sthat\scan\soccur\sfollowing\san\sOOM\sfault.
+D 2013-08-15T18:43:21.395
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b
F src/vdbeaux.c a6ea36a9dc714e1128a0173249a0532ddcab0489
F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
-F src/vdbemem.c 7ec9a78d6d4b2d4ebb4d3fd9b706065146616019
+F src/vdbemem.c c08dd81009fd6708dbb961d8ec7f82549765d680
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc
F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624
F test/analyze6.test 19151da2c4e918905d2081b74ac5c4d47fc850ab
F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88
-F test/analyze9.test b018c837164ada65f4a80dadbbcdc89cb1fff362
+F test/analyze9.test 83e74db42a49bb185e05f3a44a5d65323aba8a40
F test/analyzeA.test 1a5c40079894847976d983ca39c707aaa44b6944
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
F test/malloc9.test 2307c6ee3703b0a21391f3ea92388b4b73f9105e
-F test/mallocA.test 47006c8d70f29b030652e251cb9d35ba60289198
+F test/mallocA.test 71e4b57e640c017cf2833e51fe6e8e43e8575b73
F test/mallocAll.test 98f1be74bc9f49a858bc4f361fc58e26486798be
F test/mallocB.test bc475ab850cda896142ab935bbfbc74c24e51ed6
F test/mallocC.test 3dffe16532f109293ce1ccecd0c31dca55ef08c4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 46fec9b1a1c4616df5a634dbf9235bd13408d3a9
-R e1ce93ce8d017990abe28f4c9f5b58f9
+P 71070c9fce86103f174220e07771df99b2e01405
+R fd0e4baaf9a9ffd0fe23644f24c090cf
U dan
-Z 9abc3408e2534a3305d7999552dece52
+Z 1c4d6e6edcc7281c470c7559e77faff9
}
/*
-** Argument pCtx is actually a pointer to a database handle. Allocate and
-** return an sqlite3_value object associated with this database handle.
+** Context object passed by sqlite3Stat4ProbeSetValue() through to
+** valueNew(). See comments above valueNew() for details.
+*/
+struct ValueNewStat4Ctx {
+ Parse *pParse;
+ Index *pIdx;
+ UnpackedRecord **ppRec;
+ int iVal;
+};
+
+/*
+** Allocate and return a pointer to a new sqlite3_value object. If
+** the second argument to this function is NULL, the object is allocated
+** by calling sqlite3ValueNew().
**
-** This function used as the xAlloc callback for valueFromExpr() when
-** it is called by sqlite3ValueFromExpr().
+** Otherwise, if the second argument is non-zero, then this function is
+** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
+** already been allocated, allocate the UnpackedRecord structure that
+** that function will return to its caller here. Then return a pointer
+** an sqlite3_value within the UnpackedRecord.a[] array.
*/
-static sqlite3_value *valueNew(void *pCtx){
- return sqlite3ValueNew((sqlite3*)pCtx);
+static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
+#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
+ if( p ){
+ UnpackedRecord *pRec = p->ppRec[0];
+
+ if( pRec==0 ){
+ Index *pIdx = p->pIdx; /* Index being probed */
+ int nByte; /* Bytes of space to allocate */
+ int i; /* Counter variable */
+ int nCol = pIdx->nColumn+1; /* Number of index columns including rowid */
+
+ nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord);
+ pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte);
+ if( pRec ){
+ pRec->pKeyInfo = sqlite3IndexKeyinfo(p->pParse, pIdx);
+ if( pRec->pKeyInfo ){
+ assert( pRec->pKeyInfo->nField+1==nCol );
+ pRec->pKeyInfo->enc = ENC(db);
+ pRec->flags = UNPACKED_PREFIX_MATCH;
+ pRec->aMem = (Mem *)&pRec[1];
+ for(i=0; i<nCol; i++){
+ pRec->aMem[i].flags = MEM_Null;
+ pRec->aMem[i].type = SQLITE_NULL;
+ pRec->aMem[i].db = db;
+ }
+ }else{
+ sqlite3DbFree(db, pRec);
+ pRec = 0;
+ }
+ }
+ if( pRec==0 ) return 0;
+ p->ppRec[0] = pRec;
+ }
+
+ pRec->nField = p->iVal+1;
+ return &pRec->aMem[p->iVal];
+ }
+#endif
+ return sqlite3ValueNew(db);
}
/*
-** This function is the same as sqlite3ValueFromExpr(), except that instead
-** of allocating any required sqlite3_value object by calling
-** sqlite3ValueNew(), it does so by calling the supplied xAlloc hook.
+** Extract a value from the supplied expression in the manner described
+** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
+** using valueNew().
+**
+** If pCtx is NULL and an error occurs after the sqlite3_value object
+** has been allocated, it is freed before returning. Or, if pCtx is not
+** NULL, it is assumed that the caller will free any allocated object
+** in all cases.
*/
int valueFromExpr(
- sqlite3 *db, /* The database connection */
- Expr *pExpr, /* The expression to evaluate */
- u8 enc, /* Encoding to use */
- u8 affinity, /* Affinity to use */
- sqlite3_value **ppVal, /* Write the new value here */
- sqlite3_value *(*xAlloc)(void*), /* Used to allocate new sqlite3_value */
- void *pAlloc /* Argument passed to xAlloc */
+ sqlite3 *db, /* The database connection */
+ Expr *pExpr, /* The expression to evaluate */
+ u8 enc, /* Encoding to use */
+ u8 affinity, /* Affinity to use */
+ sqlite3_value **ppVal, /* Write the new value here */
+ struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */
){
int op;
char *zVal = 0;
}
if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
- pVal = xAlloc(pAlloc);
+ pVal = valueNew(db, pCtx);
if( pVal==0 ) goto no_mem;
if( ExprHasProperty(pExpr, EP_IntValue) ){
sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt);
sqlite3ValueApplyAffinity(pVal, affinity, enc);
}
}else if( op==TK_NULL ){
- pVal = xAlloc(pAlloc);
+ pVal = valueNew(db, pCtx);
if( pVal==0 ) goto no_mem;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
int nVal;
assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
assert( pExpr->u.zToken[1]=='\'' );
- pVal = xAlloc(pAlloc);
+ pVal = valueNew(db, pCtx);
if( !pVal ) goto no_mem;
zVal = &pExpr->u.zToken[2];
nVal = sqlite3Strlen30(zVal)-1;
no_mem:
db->mallocFailed = 1;
sqlite3DbFree(db, zVal);
- if( *ppVal==0 ) sqlite3ValueFree(pVal);
- *ppVal = 0;
+ assert( *ppVal==0 );
+ if( pCtx==0 ) sqlite3ValueFree(pVal);
return SQLITE_NOMEM;
}
u8 affinity, /* Affinity to use */
sqlite3_value **ppVal /* Write the new value here */
){
- return valueFromExpr(db, pExpr, enc, affinity, ppVal, valueNew, (void*)db);
+ return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
}
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
}
}
-/*
-** A pointer to an instance of this object is passed as the context
-** pointer to valueNewStat4() (see below.
-*/
-struct ValueNewStat4Ctx {
- Parse *pParse;
- Index *pIdx;
- UnpackedRecord **ppRec;
- int iVal;
-};
-
-/*
-** This function is used as the xAlloc function with valueFromExpr() when
-** it is called by sqlite3Stat4ProbeSetValue(). The argument points to
-** an object of type ValueNewStat4Ctx (see above).
-**
-** If it has not already been allocated, this function allocates an
-** UnpackedRecord structure and space for up to N values, where N is the
-** number of columns in the index being probed.
-*/
-static sqlite3_value *valueNewStat4(void *pCtx){
- struct ValueNewStat4Ctx *p = (struct ValueNewStat4Ctx*)pCtx;
- UnpackedRecord *pRec = p->ppRec[0];
-
- if( pRec==0 ){
- sqlite3 *db = p->pParse->db; /* Database handle */
- Index *pIdx = p->pIdx; /* Index being probed */
- int nByte; /* Bytes of space to allocate */
- int i; /* Counter variable */
- int nCol = pIdx->nColumn+1; /* Number of index columns including rowid */
-
- nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord);
- pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte);
- if( pRec ){
- pRec->pKeyInfo = sqlite3IndexKeyinfo(p->pParse, pIdx);
- if( pRec->pKeyInfo ){
- assert( pRec->pKeyInfo->nField+1==nCol );
- pRec->pKeyInfo->enc = ENC(db);
- pRec->flags = UNPACKED_PREFIX_MATCH;
- pRec->aMem = (Mem *)&pRec[1];
- for(i=0; i<nCol; i++){
- pRec->aMem[i].flags = MEM_Null;
- pRec->aMem[i].type = SQLITE_NULL;
- pRec->aMem[i].db = db;
- }
- }else{
- sqlite3DbFree(db, pRec);
- pRec = 0;
- }
- }
- if( pRec==0 ) return 0;
- p->ppRec[0] = pRec;
- }
-
- pRec->nField = p->iVal+1;
- return &pRec->aMem[p->iVal];
-}
-
/*
** This function is used to allocate and populate UnpackedRecord
** structures intended to be compared against sample index keys stored
alloc.ppRec = ppRec;
alloc.iVal = iVal;
-#if 0
- if( iVal>0 ){ *pbOk = 0; return SQLITE_OK; }
-#endif
-
if( !pExpr ){
- pVal = valueNewStat4((void*)&alloc);
+ pVal = valueNew(pParse->db, &alloc);
if( pVal ){
sqlite3VdbeMemSetNull((Mem*)pVal);
*pbOk = 1;
int iVar = pExpr->iColumn;
sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
if( (v = pParse->pReprepare) ){
- pVal = valueNewStat4((void*)&alloc);
+ pVal = valueNew(pParse->db, &alloc);
if( pVal ){
rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iVal-1]);
if( rc==SQLITE_OK ){
}
}else{
sqlite3 *db = pParse->db;
- rc = valueFromExpr(
- db, pExpr, ENC(db), affinity, &pVal, valueNewStat4, (void*)&alloc
- );
+ rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc);
*pbOk = (pVal!=0);
}