]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Performance optimization in the applyAffinity() logic inside the VDBE.
authordrh <drh@noemail.net>
Sat, 23 Aug 2014 17:21:37 +0000 (17:21 +0000)
committerdrh <drh@noemail.net>
Sat, 23 Aug 2014 17:21:37 +0000 (17:21 +0000)
FossilOrigin-Name: 25f2246be404f38b4f8dd70397cd1454d46358c4

manifest
manifest.uuid
src/vdbe.c
src/vdbeInt.h
src/vdbemem.c

index 98cd57119ed7acbdd226379054d9a47c930d5b68..8450ec16e418c4f6fb8232f6f3cb3049c5331d5e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Another\sperformance\stweak:\sSplit\sthe\ssqlite3BtreeCursorHasMoved()\sroutine\s\ninto\stwo\swith\sthe\ssecond\sroutine\snamed\ssqlite3BtreeCursorRestore().\s\sThe\sfirst\nnow\sonly\sreports\swhether\sor\snot\sthe\scursor\shas\smoved\sand\sthe\ssecond\stries\sto\nrestore\sthe\scursor.\s\sThis\sallows\sthe\ssqlite3VdbeCursorMoveto()\sroutine\sto\sbe\nrefactored\sto\savoid\sstack\spointer\smovements,\sfor\sa\snoticable\sperformance\sgain.
-D 2014-08-22T23:33:03.189
+C Performance\soptimization\sin\sthe\sapplyAffinity()\slogic\sinside\sthe\sVDBE.
+D 2014-08-23T17:21:37.343
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -284,13 +284,13 @@ F src/update.c ea336ce7b8b3fc5e316ba8f082e6445babf81059
 F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05
 F src/util.c 068dcd26354a3898ccc64ad5c4bdb95a7a15d33a
 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
-F src/vdbe.c f7f4066e4d6e3858878d76ce9288ea603e12ddf6
+F src/vdbe.c 76f9fc30dc28751900e85f615e29cdf89c069a77
 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8
-F src/vdbeInt.h f5513f2b5ac1e2c5128996c7ea23add256a301df
+F src/vdbeInt.h 764a055bc9a3e61a30ba37cd4c1826f62bcf8759
 F src/vdbeapi.c 49b8d2943d02d276b4efef114578251a3277f47d
 F src/vdbeaux.c dba006f67c9fd1b1d07ee7fb0fb38aa1905161d1
 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4
-F src/vdbemem.c 4a64659ed8e4c3b18a9238e038145ab1bdcd146f
+F src/vdbemem.c f2e162888521a9af35d608ac4c13db4991dfb417
 F src/vdbesort.c f7f5563bf7d4695ca8f3203f3bf9de96d04ed0b3
 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f
@@ -1188,7 +1188,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 3eb084390382c108e9b0ff0b29dede58ebb149bc
-R 356d2e894dc7576ad768e53fab77ee5b
+P ce123b5c592556a8cd38b01fcc91ba76231d3098
+R f59cf04b4ec2e84886c139f6982d2702
 U drh
-Z 78a9bc2b7c59c5e05ea01f499ba8646b
+Z 3f5bd9d4c135b090a54f8be497682e06
index af6d676ce0e9752b0fdd38310c8c32460842c257..4ee0b9c4819032d81d6716dbd605064bd7f81589 100644 (file)
@@ -1 +1 @@
-ce123b5c592556a8cd38b01fcc91ba76231d3098
\ No newline at end of file
+25f2246be404f38b4f8dd70397cd1454d46358c4
\ No newline at end of file
index 61adb9cccd8e6697308da064afbc39dd1d8b51db..13a076cacb28b03778006befa1527e0e6ef39bed 100644 (file)
@@ -146,7 +146,7 @@ int sqlite3_found_count = 0;
 ** already. Return non-zero if a malloc() fails.
 */
 #define Stringify(P, enc) \
-   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \
+   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
      { goto no_mem; }
 
 /*
@@ -228,8 +228,17 @@ static VdbeCursor *allocateCursor(
 ** do so without loss of information.  In other words, if the string
 ** looks like a number, convert it into a number.  If it does not
 ** look like a number, leave it alone.
+**
+** If the bTryForInt flag is true, then extra effort is made to give
+** an integer representation.  Strings that look like floating point
+** values but which have no fractional component (example: '48.00')
+** will have a MEM_Int representation when bTryForInt is true.
+**
+** If bTryForInt is false, then if the input string contains a decimal
+** point or exponential notation, the result is only MEM_Real, even
+** if there is an exact integer representation of the quantity.
 */
-static void applyNumericAffinity(Mem *pRec){
+static void applyNumericAffinity(Mem *pRec, int bTryForInt){
   double rValue;
   i64 iValue;
   u8 enc = pRec->enc;
@@ -241,10 +250,9 @@ static void applyNumericAffinity(Mem *pRec){
   }else{
     pRec->r = rValue;
     pRec->flags |= MEM_Real;
+    if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec);
   }
 }
-#define ApplyNumericAffinity(X)  \
-   if(((X)->flags&(MEM_Real|MEM_Int))==0){applyNumericAffinity(X);}
 
 /*
 ** Processing is determine by the affinity parameter:
@@ -275,15 +283,17 @@ static void applyAffinity(
     ** representation.
     */
     if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
-      sqlite3VdbeMemStringify(pRec, enc);
+      sqlite3VdbeMemStringify(pRec, enc, 1);
     }
-    pRec->flags &= ~(MEM_Real|MEM_Int);
   }else if( affinity!=SQLITE_AFF_NONE ){
     assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
              || affinity==SQLITE_AFF_NUMERIC );
-    ApplyNumericAffinity(pRec);
-    if( pRec->flags & MEM_Real ){
-      sqlite3VdbeIntegerAffinity(pRec);
+    if( (pRec->flags & MEM_Int)==0 ){
+      if( (pRec->flags & MEM_Real)==0 ){
+        applyNumericAffinity(pRec,1);
+      }else{
+        sqlite3VdbeIntegerAffinity(pRec);
+      }
     }
   }
 }
@@ -298,7 +308,7 @@ int sqlite3_value_numeric_type(sqlite3_value *pVal){
   int eType = sqlite3_value_type(pVal);
   if( eType==SQLITE_TEXT ){
     Mem *pMem = (Mem*)pVal;
-    applyNumericAffinity(pMem);
+    applyNumericAffinity(pMem, 0);
     eType = sqlite3_value_type(pVal);
   }
   return eType;
@@ -3603,7 +3613,9 @@ case OP_SeekGT: {       /* jump, in3 */
     ** blob, or NULL.  But it needs to be an integer before we can do
     ** the seek, so covert it. */
     pIn3 = &aMem[pOp->p3];
-    ApplyNumericAffinity(pIn3);
+    if( (pIn3->flags & (MEM_Int|MEM_Real))==0 ){
+      applyNumericAffinity(pIn3, 0);
+    }
     iKey = sqlite3VdbeIntValue(pIn3);
     pC->rowidIsValid = 0;
 
index 141573eef4d07088d4fdcd1a57a5ea5f60d3ff81..ba44b61e91663055627a6197fd70ba28a13f57d8 100644 (file)
@@ -418,7 +418,7 @@ void sqlite3VdbeMemSetNull(Mem*);
 void sqlite3VdbeMemSetZeroBlob(Mem*,int);
 void sqlite3VdbeMemSetRowSet(Mem*);
 int sqlite3VdbeMemMakeWriteable(Mem*);
-int sqlite3VdbeMemStringify(Mem*, int);
+int sqlite3VdbeMemStringify(Mem*, u8, u8);
 i64 sqlite3VdbeIntValue(Mem*);
 int sqlite3VdbeMemIntegerify(Mem*);
 double sqlite3VdbeRealValue(Mem*);
index 08cf40eaa803063e958928ff1d9b0c421446b4a0..572d486fc4313df4b873b7f23818fbebd4979e00 100644 (file)
@@ -223,7 +223,8 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
 ** are converted using sqlite3_snprintf().  Converting a BLOB to a string
 ** is a no-op.
 **
-** Existing representations MEM_Int and MEM_Real are *not* invalidated.
+** Existing representations MEM_Int and MEM_Real are invalidated if
+** bForce is true but are retained if bForce is false.
 **
 ** A MEM_Null value will never be passed to this function. This function is
 ** used for converting values to text for returning to the user (i.e. via
@@ -231,8 +232,7 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
 ** keys are strings. In the former case a NULL pointer is returned the
 ** user and the later is an internal programming error.
 */
-int sqlite3VdbeMemStringify(Mem *pMem, int enc){
-  int rc = SQLITE_OK;
+int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
   int fg = pMem->flags;
   const int nByte = 32;
 
@@ -248,7 +248,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){
     return SQLITE_NOMEM;
   }
 
-  /* For a Real or Integer, use sqlite3_mprintf() to produce the UTF-8
+  /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
   ** string representation of the value. Then, if the required encoding
   ** is UTF-16le or UTF-16be do a translation.
   ** 
@@ -263,8 +263,9 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){
   pMem->n = sqlite3Strlen30(pMem->z);
   pMem->enc = SQLITE_UTF8;
   pMem->flags |= MEM_Str|MEM_Term;
+  if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
   sqlite3VdbeChangeEncoding(pMem, enc);
-  return rc;
+  return SQLITE_OK;
 }
 
 /*
@@ -877,7 +878,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
     sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */
   }else{
     assert( (pVal->flags&MEM_Blob)==0 );
-    sqlite3VdbeMemStringify(pVal, enc);
+    sqlite3VdbeMemStringify(pVal, enc, 0);
     assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
   }
   assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0