]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add header comments on new routines. Rework the sqlite3Stat4Column() routine
authordrh <drh@noemail.net>
Sat, 28 Jun 2014 16:06:44 +0000 (16:06 +0000)
committerdrh <drh@noemail.net>
Sat, 28 Jun 2014 16:06:44 +0000 (16:06 +0000)
so that is (in theory) able to deal with corrupt samples.

FossilOrigin-Name: ef5cdf949bb53a2958fa34e176b4b9eeda269de5

manifest
manifest.uuid
src/vdbemem.c

index 624fcba2febac055b4a315e0ec138d4992b0acad..7600c076fe5240b37a355e7de875383d4b20b774 100644 (file)
--- 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
index f498e3b5e9c4e4c5e113ac77eee727453692f16c..2e226ad3716a23bd60295d64c253532433a97919 100644 (file)
@@ -1 +1 @@
-dfb09db6d412f3bc2a71bda393813783580dbad1
\ No newline at end of file
+ef5cdf949bb53a2958fa34e176b4b9eeda269de5
\ No newline at end of file
index 7e5c912f394302e6e1597b6a1501b944fdda260c..cf44aa7e2de71acc2cbcd3fadf6263aab1e3fb4f 100644 (file)
@@ -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; 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;
 }
 
 /*