]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Floating point and 64-bit integer constants store in the virtual
authordrh <drh@noemail.net>
Tue, 23 Oct 2007 15:39:45 +0000 (15:39 +0000)
committerdrh <drh@noemail.net>
Tue, 23 Oct 2007 15:39:45 +0000 (15:39 +0000)
machine opcodes in binary, not as text.  Performance improvement.
Ticket #2733. (CVS 4507)

FossilOrigin-Name: 7e30fd6a09899842c922b044714dc66796e545d4

manifest
manifest.uuid
src/expr.c
src/sqliteInt.h
src/test1.c
src/util.c
src/vdbe.c
src/vdbe.h
src/vdbeaux.c
test/alter.test

index f5b4691e0787871d720062a0c84a905478d897e1..ab77c5b5e4a526fe9bb878843b41a3589049ec05 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\slimit\sassertions\sin\svdbe.c.\s\sTicket\s#2740.\s(CVS\s4506)
-D 2007-10-23T14:55:07
+C Floating\spoint\sand\s64-bit\sinteger\sconstants\sstore\sin\sthe\svirtual\nmachine\sopcodes\sin\sbinary,\snot\sas\stext.\s\sPerformance\simprovement.\nTicket\s#2733.\s(CVS\s4507)
+D 2007-10-23T15:39:45
 F Makefile.in 30c7e3ba426ddb253b8ef037d1873425da6009a8
 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -90,7 +90,7 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
 F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
 F src/delete.c 849846d06d29851dde0d9f424a5de5817eb140d1
 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
-F src/expr.c 20a45339a6ba1e98c07e7f2039e8ffad0290fb77
+F src/expr.c 650f30eba63f9635d5f31a6717c4db7d720eae2c
 F src/func.c e8e8978804ba453e9e1377db8824c90871b53cfb
 F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
 F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
@@ -133,11 +133,11 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 82089379833e361ba8a2ae65316a2173785300c0
 F src/sqlite.h.in 06c1bbf810800ad11313e646df99b35d90d1c7df
 F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
-F src/sqliteInt.h 3fa9f4e9d2f07e162509f75d827d32f41fcd4f30
+F src/sqliteInt.h ae43aebc3c971b0949fd1a672431c4c01386848a
 F src/sqliteLimit.h 1bcbbdfa856f8b71b561abb31edb864b0eca1d12
 F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
 F src/tclsqlite.c 29bb44a88e02ca4d2017113b7b1acc839582d57a
-F src/test1.c e4785f9b339d27fb300da8bfb0ba27af8e7bcee0
+F src/test1.c 0e6fe5449ef9e7289bcaf904e9e3a2ea20650b32
 F src/test2.c 77b34303883b9d722c65a6879bb0163a400e3789
 F src/test3.c 73c1fd55d1ece61f295a6b9204fd97a139de86ae
 F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
@@ -163,13 +163,13 @@ F src/tokenize.c 67e42600ab34f976f2b1288c499ad6c98d652f0e
 F src/trigger.c 724a77d54609a33bde90618934fbeddfcc729a10
 F src/update.c e89b980b443d44b68bfc0b1746cdb6308e049ac9
 F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
-F src/util.c 49263637e0f228411201501ddfd1138338d6322c
+F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
 F src/vacuum.c a5e51c77370c1a6445e86d42abfc43867cdd482d
-F src/vdbe.c b21ea40c5b0ae4379394fa2aad92909e1a8736b5
-F src/vdbe.h 03a0fa17f6753a24d6cb585d7a362944a2c115aa
+F src/vdbe.c 6a577531074e5bcd86c56655eb52512aef384201
+F src/vdbe.h 856360de71d4bdda71fbb534087668667924e41a
 F src/vdbeInt.h 630145b9bfaa19190ab491f52658a7db550f2247
 F src/vdbeapi.c 21b69e71ab39d8e694c9cdb556a74dbefba9ebda
-F src/vdbeaux.c 99534543766eec8eb3727e6f9dc8ed64d95f1f2d
+F src/vdbeaux.c 7bb91382da8f4e904650ed4a393f7ae83bee8669
 F src/vdbeblob.c 82f51cdf9b0c0af729732fde48c824e498c0a1ca
 F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
 F src/vdbemem.c 123994fcd344993d2fb050a83b91b341bbbd08b4
@@ -178,7 +178,7 @@ F src/where.c 44042c8b9d0d054cc318c3a0df052215ebf49d2d
 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/all.test b59d1bd8b0c1d4a08b845e8af48fd43926f01f11
-F test/alter.test 908659f97a0f97504da2f71ebc14e84b440a52ab
+F test/alter.test a87b7933d41c713c53341abe4eb014d0e273119e
 F test/alter2.test 489140038c13f4f9c76a0a8243eb1249f44d4ce1
 F test/alter3.test 8ce6b9c5605b3cfe7b901f454ecaf174c4f93e31
 F test/altermalloc.test 29d4a8400277efb4ba8ffe90804c6dc2fdfbf063
@@ -584,7 +584,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P c36500871e85b55cb0804d5c9e88fa6861a507a9
-R 407160c3c038e7e8a4d0ba1b11794db6
+P 27f846d089ebe9e4970a2499ad4e2e98773d2e78
+R 29246301e1a21448d6de393ea1067bfb
 U drh
-Z 0e481a3e67cd54e4694f0f724a957ac6
+Z 4278cd4e208f23a96cec913f943e3d86
index ce66008041ec87b2329eab51bce0dd2157d3417e..141d093235e78e88091e4e5d2cee6fe1b32d7350 100644 (file)
@@ -1 +1 @@
-27f846d089ebe9e4970a2499ad4e2e98773d2e78
\ No newline at end of file
+7e30fd6a09899842c922b044714dc66796e545d4
\ No newline at end of file
index 0a7091a09d1bfd4cd2a8dc078f79a77c0664e57d..f196ba19c482a1da86a9efbbd768c80bf4ca5c25 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.313 2007/09/18 15:55:07 drh Exp $
+** $Id: expr.c,v 1.314 2007/10/23 15:39:45 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1680,20 +1680,54 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
 }
 #endif /* SQLITE_OMIT_SUBQUERY */
 
+/*
+** Duplicate an 8-byte value
+*/
+static char *dup8bytes(Vdbe *v, const char *in){
+  char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8);
+  if( out ){
+    memcpy(out, in, 8);
+  }
+  return out;
+}
+
+/*
+** Generate an instruction that will put the floating point
+** value described by z[0..n-1] on the stack.
+*/
+static void codeReal(Vdbe *v, const char *z, int n, int negateFlag){
+  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
+  if( z ){
+    double value;
+    char *zV;
+    sqlite3AtoF(z, &value);
+    if( negateFlag ) value = -value;
+    zV = dup8bytes(v, (char*)&value);
+    sqlite3VdbeOp3(v, OP_Real, 0, 0, zV, P3_REAL);
+  }
+}
+
+
 /*
 ** Generate an instruction that will put the integer describe by
 ** text z[0..n-1] on the stack.
 */
-static void codeInteger(Vdbe *v, const char *z, int n){
+static void codeInteger(Vdbe *v, const char *z, int n, int negateFlag){
   assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
   if( z ){
     int i;
     if( sqlite3GetInt32(z, &i) ){
+      if( negateFlag ) i = -i;
       sqlite3VdbeAddOp(v, OP_Integer, i, 0);
-    }else if( sqlite3FitsIn64Bits(z) ){
-      sqlite3VdbeOp3(v, OP_Int64, 0, 0, z, n);
+    }else if( sqlite3FitsIn64Bits(z, negateFlag) ){
+      i64 value;
+      char *zV;
+      sqlite3Atoi64(z, &value);
+      if( negateFlag ) value = -value;
+      zV = dup8bytes(v, (char*)&value);
+      sqlite3VdbeOp3(v, OP_Int64, 0, 0, zV, P3_INT64);
     }else{
-      sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n);
+      codeReal(v, z, n, negateFlag);
     }
   }
 }
@@ -1769,15 +1803,16 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
       break;
     }
     case TK_INTEGER: {
-      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n);
+      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0);
+      break;
+    }
+    case TK_FLOAT: {
+      codeReal(v, (char*)pExpr->token.z, pExpr->token.n, 0);
       break;
     }
-    case TK_FLOAT:
     case TK_STRING: {
-      assert( TK_FLOAT==OP_Real );
-      assert( TK_STRING==OP_String8 );
       sqlite3DequoteExpr(pParse->db, pExpr);
-      sqlite3VdbeOp3(v, op, 0, 0, (char*)pExpr->token.z, pExpr->token.n);
+      sqlite3VdbeOp3(v,OP_String8, 0, 0, (char*)pExpr->token.z, pExpr->token.n);
       break;
     }
     case TK_NULL: {
@@ -1879,13 +1914,11 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
       assert( pLeft );
       if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
         Token *p = &pLeft->token;
-        char *z = sqlite3MPrintf(pParse->db, "-%.*s", p->n, p->z);
         if( pLeft->op==TK_FLOAT ){
-          sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);
+          codeReal(v, (char*)p->z, p->n, 1);
         }else{
-          codeInteger(v, z, p->n+1);
+          codeInteger(v, (char*)p->z, p->n, 1);
         }
-        sqlite3_free(z);
         break;
       }
       /* Fall through into TK_NOT */
index 8b85beac6b621f74a2f80b423c946009da0ba498..201ab09adc30406b1658b8f7f6f9ab231c797f3e 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.614 2007/10/04 18:11:16 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.615 2007/10/23 15:39:45 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1783,7 +1783,7 @@ int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
 int sqlite3AtoF(const char *z, double*);
 char *sqlite3_snprintf(int,char*,const char*,...);
 int sqlite3GetInt32(const char *, int*);
-int sqlite3FitsIn64Bits(const char *);
+int sqlite3FitsIn64Bits(const char *, int);
 int sqlite3Utf16ByteLen(const void *pData, int nChar);
 int sqlite3Utf8CharLen(const char *pData, int nByte);
 int sqlite3Utf8Read(const u8*, const u8*, const u8**);
index b1b49a3080bebb2c2cd170e20d871d51813f72c9..f7abaf9a5539b617de0065ff23220874c890ca72 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.278 2007/10/23 14:49:59 drh Exp $
+** $Id: test1.c,v 1.279 2007/10/23 15:39:45 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -1131,7 +1131,7 @@ static int sqlite3_mprintf_int(
 ** *pValue to that integer and return true.  Otherwise return false.
 */
 static int sqlite3GetInt64(const char *zNum, i64 *pValue){
-  if( sqlite3FitsIn64Bits(zNum) ){
+  if( sqlite3FitsIn64Bits(zNum, 0) ){
     sqlite3Atoi64(zNum, pValue);
     return 1;
   }
index 722df63e961d3dcc494df82ccc942a8241d13aec..318bd25ade4413274507051000c643acd1dd723d 100644 (file)
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.212 2007/09/01 10:01:13 danielk1977 Exp $
+** $Id: util.c,v 1.213 2007/10/23 15:39:45 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -376,7 +376,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum){
 ** 9223373036854775808 will not fit in 64 bits.  So it seems safer to return
 ** false.
 */
-int sqlite3FitsIn64Bits(const char *zNum){
+int sqlite3FitsIn64Bits(const char *zNum, int negFlag){
   int i, c;
   int neg = 0;
   if( *zNum=='-' ){
@@ -385,6 +385,7 @@ int sqlite3FitsIn64Bits(const char *zNum){
   }else if( *zNum=='+' ){
     zNum++;
   }
+  if( negFlag ) neg = 1-neg;
   while( *zNum=='0' ){
     zNum++;   /* Skip leading zeros.  Ticket #2454 */
   }
index 1eec0bcc93358f1f289f2fa52f66f590f38d3833..e7197fca51959b9050f02c6c1d5636366eef740f 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.652 2007/10/23 14:55:07 drh Exp $
+** $Id: vdbe.c,v 1.653 2007/10/23 15:39:45 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -705,34 +705,26 @@ case OP_Integer: {
 
 /* Opcode: Int64 * * P3
 **
-** P3 is a string representation of an integer.  Convert that integer
-** to a 64-bit value and push it onto the stack.
+** P3 is a pointer to a 64-bit integer value.
+** Push  that value onto  the stack.
 */
 case OP_Int64: {
   pTos++;
   assert( pOp->p3!=0 );
-  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
-  pTos->z = pOp->p3;
-  pTos->n = strlen(pTos->z);
-  pTos->enc = SQLITE_UTF8;
-  pTos->u.i = sqlite3VdbeIntValue(pTos);
-  pTos->flags |= MEM_Int;
+  pTos->flags = MEM_Int;
+  memcpy(&pTos->u.i, pOp->p3, 8);
   break;
 }
 
 /* Opcode: Real * * P3
 **
-** The string value P3 is converted to a real and pushed on to the stack.
+** P3 is a pointer to a 64-bit floating point value.  Push that value
+** onto the stack.
 */
 case OP_Real: {            /* same as TK_FLOAT, */
   pTos++;
-  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
-  pTos->z = pOp->p3;
-  pTos->n = strlen(pTos->z);
-  pTos->enc = SQLITE_UTF8;
-  pTos->r = sqlite3VdbeRealValue(pTos);
-  pTos->flags |= MEM_Real;
-  sqlite3VdbeChangeEncoding(pTos, encoding);
+  pTos->flags = MEM_Real;
+  memcpy(&pTos->r, pOp->p3, 8);
   break;
 }
 
index 75f186cb07c9a1a8ec1edeeada71e3960024d350..c2280761c7b2831a44bb625ac9a97a4b5032716f 100644 (file)
@@ -15,7 +15,7 @@
 ** or VDBE.  The VDBE implements an abstract machine that runs a
 ** simple program to access and modify the underlying database.
 **
-** $Id: vdbe.h,v 1.113 2007/08/30 01:19:59 drh Exp $
+** $Id: vdbe.h,v 1.114 2007/10/23 15:39:45 drh Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
@@ -72,6 +72,8 @@ typedef struct VdbeOpList VdbeOpList;
 #define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */
 #define P3_VTAB     (-10) /* P3 is a pointer to an sqlite3_vtab structure */
 #define P3_MPRINTF  (-11) /* P3 is a string obtained from sqlite3_mprintf() */
+#define P3_REAL     (-12) /* P3 is a 64-bit floating point value */
+#define P3_INT64    (-13) /* P3 is a 64-bit signed integer */
 
 /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
 ** is made.  That copy is freed when the Vdbe is finalized.  But if the
index df79d8bf4a6d414a7e1eed1a600e34604462d044..22215b207056ca597c1574bcf0d836ef3d14402f 100644 (file)
@@ -432,16 +432,15 @@ static void freeEphemeralFunction(FuncDef *pDef){
 static void freeP3(int p3type, void *p3){
   if( p3 ){
     switch( p3type ){
+      case P3_REAL:
+      case P3_INT64:
+      case P3_MPRINTF:
       case P3_DYNAMIC:
       case P3_KEYINFO:
       case P3_KEYINFO_HANDOFF: {
         sqlite3_free(p3);
         break;
       }
-      case P3_MPRINTF: {
-        sqlite3_free(p3);
-        break;
-      }
       case P3_VDBEFUNC: {
         VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
         freeEphemeralFunction(pVdbeFunc->pFunc);
@@ -631,6 +630,16 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){
       zP3 = zTemp;
       break;
     }
+    case P3_INT64: {
+      sqlite3_snprintf(nTemp, zTemp, "%lld", *(sqlite3_int64*)pOp->p3);
+      zP3 = zTemp;
+      break;
+    }
+    case P3_REAL: {
+      sqlite3_snprintf(nTemp, zTemp, "%.16g", *(double*)pOp->p3);
+      zP3 = zTemp;
+      break;
+    }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
     case P3_VTAB: {
       sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p3;
index 58b42980a4b53ce5ca002f0c0383f644f963dd2e..f994fc5da4fb03a325386d32b82fae22fea5f94f 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is testing the ALTER TABLE statement.
 #
-# $Id: alter.test,v 1.26 2007/10/09 08:29:32 danielk1977 Exp $
+# $Id: alter.test,v 1.27 2007/10/23 15:39:46 drh Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -638,10 +638,10 @@ do_test alter-7.1 {
     CREATE TABLE t1(a TEXT COLLATE BINARY);
     ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE;
     INSERT INTO t1 VALUES(1,'-2');
-    INSERT INTO t1 VALUES(5.4e-8,'5.4e-8');
+    INSERT INTO t1 VALUES(5.4e-08,'5.4e-08');
     SELECT typeof(a), a, typeof(b), b FROM t1;
   }
-} {text 1 integer -2 text 5.4e-8 real 5.4e-08}
+} {text 1 integer -2 text 5.4e-08 real 5.4e-08}
 
 # Make sure that when a column is added by ALTER TABLE ADD COLUMN and has
 # a default value that the default value is used by aggregate functions.