-C Fix\sa\sproblem\swith\susing\sstat4\ssamples\sof\stype\stext\swhen\sestimating\sthe\srows\svisited\sby\sa\srange-query/skip-scan\sloop.
-D 2014-06-28T15:26:10.708
+C Add\sheader\scomments\son\snew\sroutines.\s\sRework\sthe\ssqlite3Stat4Column()\sroutine\nso\sthat\sis\s(in\stheory)\sable\sto\sdeal\swith\scorrupt\ssamples.
+D 2014-06-28T16:06:44.822
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in b03432313a3aad96c706f8164fb9f5307eaf19f5
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4
F src/vdbeaux.c e493f38758c4b8f4ca2007cf6a700bd405d192f3
F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac
-F src/vdbemem.c 8228bc32622716d26ffd902ceca7b31690744fef
+F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394
F src/vdbesort.c 44441d73b08b3a638dcdb725afffb87c6574ad27
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P d186d1ac3c47f0d814636c4b8386a6065a294750
-R 737af1ae1f9d5e706af49b9d72dc98eb
-U dan
-Z c44a7d177df302c14a246c1d5d1d90b5
+P dfb09db6d412f3bc2a71bda393813783580dbad1
+R a461409aefe23981a1fbdd4418e17b64
+U drh
+Z a2fad482dc40a73ef09e3690c963a5aa
}
}
+/*
+** Attempt to extract a value from pExpr and use it to construct *ppVal.
+**
+** If pAlloc is not NULL, then an UnpackedRecord object is created for
+** pAlloc if one does not exist and the new value is added to the
+** UnpackedRecord object.
+**
+** A value is extracted in the following cases:
+**
+** * (pExpr==0). In this case the value is assumed to be an SQL NULL,
+**
+** * The expression is a bound variable, and this is a reprepare, or
+**
+** * The expression is a literal value.
+**
+** On success, *ppVal is made to point to the extracted value. The caller
+** is responsible for ensuring that the value is eventually freed.
+*/
static int stat4ValueFromExpr(
Parse *pParse, /* Parse context */
Expr *pExpr, /* The expression to extract a value from */
u8 affinity, /* Affinity to use */
- struct ValueNewStat4Ctx *pAlloc,/* How to allocate space */
+ struct ValueNewStat4Ctx *pAlloc,/* How to allocate space. Or NULL */
sqlite3_value **ppVal /* OUT: New value object (or NULL) */
){
int rc = SQLITE_OK;
return stat4ValueFromExpr(pParse, pExpr, affinity, 0, ppVal);
}
+/*
+** Extract the iCol-th column from the nRec-byte record in pRec. Write
+** the column value into *ppVal. If *ppVal is initially NULL then a new
+** sqlite3_value object is allocated.
+**
+** If *ppVal is initially NULL then the caller is responsible for
+** ensuring that the value written into *ppVal is eventually freed.
+*/
int sqlite3Stat4Column(
sqlite3 *db, /* Database handle */
const void *pRec, /* Pointer to buffer containing record */
int iCol, /* Column to extract */
sqlite3_value **ppVal /* OUT: Extracted value */
){
- int rc = SQLITE_OK;
- Mem *pMem = *ppVal;
- if( pMem==0 ){
- pMem = (Mem*)sqlite3ValueNew(db);
- if( pMem==0 ){
- rc = SQLITE_NOMEM;
- }
+ u32 t; /* a column type code */
+ int nHdr; /* Size of the header in the record */
+ int iHdr; /* Next unread header byte */
+ int iField; /* Next unread data byte */
+ int szField; /* Size of the current data field */
+ int i; /* Column index */
+ u8 *a = (u8*)pRec; /* Typecast byte array */
+ Mem *pMem = *ppVal; /* Write result into this Mem object */
+
+ assert( iCol>0 );
+ iHdr = getVarint32(a, nHdr);
+ if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT;
+ iField = nHdr;
+ for(i=0; i<=iCol; i++){
+ iHdr += getVarint32(&a[iHdr], t);
+ testcase( iHdr==nHdr );
+ testcase( iHdr==nHdr+1 );
+ if( iHdr>nHdr ) return SQLITE_CORRUPT_BKPT;
+ szField = sqlite3VdbeSerialTypeLen(t);
+ iField += szField;
}
-
- if( rc==SQLITE_OK ){
- u32 t;
- int nHdr;
- int iHdr;
- int iField;
- int i;
- u8 *a = (u8*)pRec;
-
- iHdr = getVarint32(a, nHdr);
- iField = nHdr;
- for(i=0; i<iCol; i++){
- iHdr += getVarint32(&a[iHdr], t);
- iField += sqlite3VdbeSerialTypeLen(t);
- }
-
- iHdr = getVarint32(&a[iHdr], t);
- pMem->enc = ENC(db);
- sqlite3VdbeSerialGet(&a[iField], t, pMem);
+ testcase( iField==nRec );
+ testcase( iField==nRec+1 );
+ if( iField>nRec ) return SQLITE_CORRUPT_BKPT;
+ if( pMem==0 ){
+ pMem = *ppVal = sqlite3ValueNew(db);
+ if( pMem==0 ) return SQLITE_NOMEM;
}
-
- *ppVal = pMem;
- return rc;
+ sqlite3VdbeSerialGet(&a[iField-szField], t, pMem);
+ pMem->enc = ENC(db);
+ return SQLITE_OK;
}
/*