From: drh Date: Sat, 28 Jun 2014 16:06:44 +0000 (+0000) Subject: Add header comments on new routines. Rework the sqlite3Stat4Column() routine X-Git-Tag: version-3.8.6~92^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0288b21e54e16ec511aaba9825e4655980a9f059;p=thirdparty%2Fsqlite.git Add header comments on new routines. Rework the sqlite3Stat4Column() routine so that is (in theory) able to deal with corrupt samples. FossilOrigin-Name: ef5cdf949bb53a2958fa34e176b4b9eeda269de5 --- diff --git a/manifest b/manifest index 624fcba2fe..7600c076fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -289,7 +289,7 @@ F src/vdbeInt.h 5df5e9afe9b7839cd17256220fc4f7af84b8b1cd 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 @@ -1182,7 +1182,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 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 diff --git a/manifest.uuid b/manifest.uuid index f498e3b5e9..2e226ad371 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfb09db6d412f3bc2a71bda393813783580dbad1 \ No newline at end of file +ef5cdf949bb53a2958fa34e176b4b9eeda269de5 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 7e5c912f39..cf44aa7e2d 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1152,11 +1152,29 @@ void sqlite3AnalyzeFunctions(void){ } } +/* +** 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; @@ -1269,6 +1287,14 @@ int sqlite3Stat4ValueFromExpr( 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 */ @@ -1276,37 +1302,37 @@ int sqlite3Stat4Column( 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; ienc = 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; } /*