-C Coverage\stesting\sof\spragma.c.\s(CVS\s1744)
-D 2004-06-26T19:35:30
+C Fix\sa\sbug\sin\sthe\shandling\sof\sMems\sinside\sof\svdbe.c.\s(CVS\s1745)
+D 2004-06-27T01:56:33
F Makefile.in cb7a9889c38723f72b2506c4236ff30a05ff172b
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/utf.c a8fb39c94ae4ef6606d5216b6f05d9b86f6901b2
F src/util.c 43d0289d49f43c66847ebbeddfb85a2a0d1ddd2d
F src/vacuum.c 353c7f69dbeb6738434d81798465cc0698844640
-F src/vdbe.c 423b55e65501ef2b60d8dedabe8d76d06ea62d99
+F src/vdbe.c b750a731c90567b77ed6e0cd455ac868953d3a72
F src/vdbe.h 2d87155e31e84bb00cdc48cc1ce6987a3a484250
-F src/vdbeInt.h 22ab717b69074fe7a28f64e35a39bd436ad9d150
-F src/vdbeapi.c d3659f3f2982e79c06ab8e338604a39e0ea0d2d3
+F src/vdbeInt.h d83fd7389838453d8392915c21f432014afc99cf
+F src/vdbeapi.c e92bda928f2fe93a9a77a62bd95642563bbcdea1
F src/vdbeaux.c e7201e3f129439bc64d2ff79b54001adc2c95539
-F src/vdbemem.c d37e4033f7350e542f715c061bffe23feb51bc9e
+F src/vdbemem.c e8ae1f56ad16d5b01119e8dc1d25e913e06c3128
F src/where.c 6507074d8ce3f78e7a4cd33f667f11e62020553e
F test/all.test d591e074013248176402a16a0fb6fc82d241bad5
F test/attach.test 3acdffccbf5f78b07746771b9490758718e28856
F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
F test/btree7.test 429b96cfef5b51a7d512cfb4b5b3e453384af293
F test/capi2.test fe61f341e953f73c29bacfcbdaf688cd7b0e0d38
-F test/capi3.test 6528034f21c4e8e404032124cb58b14ce934598c
+F test/capi3.test ac53507f69b14fe026634afa09e6512f678f161d
F test/collate1.test 2ee4fa3a47a652ccf56c5ddf65dcc44d9bad82ef
F test/collate2.test c1a3b41f761b28853c5696037f92de928f93233b
F test/collate3.test e60b428e07ec945492ba90ff1c895902ee3a8a50
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 563ba3ac02f64da27ab17f3edbe8e56bfd0293fb
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P b69b4fe8adff83a26e3566613bea8b477a26e8a4
-R 72fd52c0e274fc83fa1945dfd7a6deb8
+P 0f9c0f0aa9188c46c65cb92203687f37884f685a
+R 890a4b373e4b15aa9e98bea1cb54b3e0
U drh
-Z 03157110b37f81d3fef2f16d6fba5e75
+Z bd1af074bc92b88e71778888aba3c921
-0f9c0f0aa9188c46c65cb92203687f37884f685a
\ No newline at end of file
+ad65c6e24e15966d5fd15d60f81487ff97788da4
\ No newline at end of file
** 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.389 2004/06/26 08:38:25 danielk1977 Exp $
+** $Id: vdbe.c,v 1.390 2004/06/27 01:56:33 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
** Any prior string or real representation is invalidated.
** NULLs are converted into 0.
*/
-#define Integerify(P, enc) \
- if((P)->flags!=MEM_Int){ sqlite3VdbeMemIntegerify(P); }
+#define Integerify(P) sqlite3VdbeMemIntegerify(P)
/*
-** Get a valid Real representation for the given stack element.
+** Convert P so that it has type MEM_Real.
**
-** Any prior string or integer representation is retained.
+** Any prior string or integer representation is invalidated.
** NULLs are converted into 0.0.
*/
-#define Realify(P,enc) \
- if(((P)->flags&MEM_Real)==0){ sqlite3VdbeMemRealify(P); }
+#define Realify(P) sqlite3VdbeMemRealify(P)
/*
** Argument pMem points at a memory cell that will be passed to a
sqlite3VdbeMemNulTerminate(pRec);
if( pRec->flags&MEM_Str && sqlite3IsNumber(pRec->z, &realnum, enc) ){
if( realnum ){
- Realify(pRec, enc);
+ Realify(pRec);
}else{
- Integerify(pRec, enc);
+ Integerify(pRec);
}
}
}
pTos->z = pOp->p3;
pTos->n = strlen(pTos->z);
pTos->enc = SQLITE_UTF8;
- Integerify(pTos, 0);
+ pTos->i = sqlite3VdbeIntValue(pTos);
+ pTos->flags |= MEM_Int;
}
break;
}
pTos->z = pOp->p3;
pTos->n = strlen(pTos->z);
pTos->enc = SQLITE_UTF8;
- Realify(pTos, 0);
+ pTos->r = sqlite3VdbeRealValue(pTos);
+ pTos->flags |= MEM_Real;
break;
}
pTos->flags = MEM_Int;
}else{
double a, b;
- Realify(pTos, db->enc);
- Realify(pNos, db->enc);
- a = pTos->r;
- b = pNos->r;
+ a = sqlite3VdbeRealValue(pTos);
+ b = sqlite3VdbeRealValue(pNos);
switch( pOp->opcode ){
case OP_Add: b += a; break;
case OP_Subtract: b -= a; break;
pTos->flags = MEM_Null;
break;
}
- Integerify(pTos, db->enc);
- Integerify(pNos, db->enc);
- a = pTos->i;
- b = pNos->i;
+ a = sqlite3VdbeIntValue(pTos);
+ b = sqlite3VdbeIntValue(pNos);
switch( pOp->opcode ){
case OP_BitAnd: a &= b; break;
case OP_BitOr: a |= b; break;
case OP_ShiftRight: a >>= b; break;
default: /* CANT HAPPEN */ break;
}
- /* FIX ME: Because constant P3 values sometimes need to be translated,
- ** the following assert() can fail. When P3 is always in the native text
- ** encoding, this assert() will be valid again. Until then, the Release()
- ** is neeed instead.
- assert( (pTos->flags & MEM_Dyn)==0 );
- assert( (pNos->flags & MEM_Dyn)==0 );
- */
Release(pTos);
pTos--;
Release(pTos);
*/
case OP_AddImm: {
assert( pTos>=p->aStack );
- Integerify(pTos, db->enc);
+ Integerify(pTos);
pTos->i += pOp->p1;
break;
}
if( pTos->flags & MEM_Int ){
v = pTos->i + (pOp->p1!=0);
}else{
- Realify(pTos, db->enc);
+ Realify(pTos);
v = (int)pTos->r;
if( pTos->r>(double)v ) v++;
if( pOp->p1 && pTos->r==(double)v ) v++;
if( !sqlite3IsNumber(pTos->z, 0, db->enc) ){
goto mismatch;
}
- Realify(pTos, db->enc);
+ Realify(pTos);
v = (int)pTos->r;
r = (double)v;
if( r!=pTos->r ){
if( pTos->flags & MEM_Null ){
v1 = 2;
}else{
- Integerify(pTos, db->enc);
+ Integerify(pTos);
v1 = pTos->i==0;
}
if( pNos->flags & MEM_Null ){
v2 = 2;
}else{
- Integerify(pNos, db->enc);
+ Integerify(pNos);
v2 = pNos->i==0;
}
if( pOp->opcode==OP_And ){
}else if( pTos->flags & MEM_Null ){
/* Do nothing */
}else{
- Realify(pTos, db->enc);
- Release(pTos);
+ Realify(pTos);
if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
pTos->r = -pTos->r;
}
case OP_Not: {
assert( pTos>=p->aStack );
if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */
- Integerify(pTos, db->enc);
- Release(pTos);
+ Integerify(pTos);
+ assert( (pTos->flags & MEM_Dyn)==0 );
pTos->i = !pTos->i;
pTos->flags = MEM_Int;
break;
case OP_BitNot: {
assert( pTos>=p->aStack );
if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */
- Integerify(pTos, db->enc);
- Release(pTos);
+ Integerify(pTos);
+ assert( (pTos->flags & MEM_Dyn)==0 );
pTos->i = ~pTos->i;
pTos->flags = MEM_Int;
break;
if( pTos->flags & MEM_Null ){
c = pOp->p1;
}else{
- Integerify(pTos, db->enc);
- c = pTos->i;
+ c = sqlite3VdbeIntValue(pTos);
if( pOp->opcode==OP_IfNot ) c = !c;
}
- /* FIX ME: Because constant P3 values sometimes need to be translated,
- ** the following assert() can fail. When P3 is always in the native text
- ** encoding, this assert() will be valid again. Until then, the Release()
- ** is neeed instead.
- assert( (pTos->flags & MEM_Dyn)==0 );
- */
Release(pTos);
pTos--;
if( c ) pc = pOp->p2-1;
if( addRowid ){
pRowid = &pTos[0-nField];
assert( pRowid>=p->aStack );
- Integerify(pRowid, db->enc);
+ Integerify(pRowid);
serial_type = sqlite3VdbeSerialType(pRowid);
nData += sqlite3VdbeSerialTypeLen(serial_type);
nHdr += sqlite3VarintLen(serial_type);
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( db->aDb[pOp->p1].pBt!=0 );
assert( pTos>=p->aStack );
- Integerify(pTos, db->enc);
+ Integerify(pTos);
/* See note about index shifting on OP_ReadCookie */
rc = sqlite3BtreeUpdateMeta(db->aDb[pOp->p1].pBt, 1+pOp->p2, (int)pTos->i);
- Release(pTos);
+ assert( (pTos->flags & MEM_Dyn)==0 );
pTos--;
break;
}
Cursor *pCur;
assert( pTos>=p->aStack );
- Integerify(pTos, db->enc);
+ Integerify(pTos);
iDb = pTos->i;
+ assert( (pTos->flags & MEM_Dyn)==0 );
pTos--;
assert( iDb>=0 && iDb<db->nDb );
pX = db->aDb[iDb].pBt;
wrFlag = pOp->opcode==OP_OpenWrite;
if( p2<=0 ){
assert( pTos>=p->aStack );
- Integerify(pTos, db->enc);
+ Integerify(pTos);
p2 = pTos->i;
+ assert( (pTos->flags & MEM_Dyn)==0 );
pTos--;
if( p2<2 ){
sqlite3SetString(&p->zErrMsg, "root page number less than 2", (char*)0);
if( pC->intKey ){
i64 iKey;
assert( !pOp->p3 );
- Integerify(pTos, db->enc);
+ Integerify(pTos);
iKey = intToKey(pTos->i);
if( pOp->p2==0 && pOp->opcode==OP_MoveGe ){
pC->movetoTarget = iKey;
pC->deferredMoveto = 1;
- Release(pTos);
+ assert( (pTos->flags & MEM_Dyn)==0 );
pTos--;
break;
}
/* Pop the value R off the top of the stack
*/
assert( pNos>=p->aStack );
- Integerify(pTos, db->enc);
+ Integerify(pTos);
R = pTos->i;
+ assert( (pTos->flags & MEM_Dyn)==0 );
pTos--;
assert( i>=0 && i<=p->nCursor );
pCx = p->apCsr[i];
pKeylist->pNext = p->pList;
p->pList = pKeylist;
}
- Integerify(pTos, db->enc);
+ Integerify(pTos);
pKeylist->aKey[pKeylist->nUsed++] = pTos->i;
- Release(pTos);
+ assert( (pTos->flags & MEM_Dyn)==0 );
pTos--;
break;
}
int sqlite3VdbeMemMakeWriteable(Mem*);
int sqlite3VdbeMemDynamicify(Mem*);
int sqlite3VdbeMemStringify(Mem*, int);
+i64 sqlite3VdbeIntValue(Mem*);
int sqlite3VdbeMemIntegerify(Mem*);
+double sqlite3VdbeRealValue(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
return 0;
}
double sqlite3_value_double(sqlite3_value *pVal){
- Mem *pMem = (Mem *)pVal;
- sqlite3VdbeMemRealify(pMem);
- return pMem->r;
+ return sqlite3VdbeRealValue((Mem*)pVal);
}
int sqlite3_value_int(sqlite3_value *pVal){
- Mem *pMem = (Mem *)pVal;
- sqlite3VdbeMemIntegerify(pMem);
- return (int)pVal->i;
+ return sqlite3VdbeIntValue((Mem*)pVal);
}
sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
- Mem *pMem = (Mem *)pVal;
- sqlite3VdbeMemIntegerify(pMem);
- return pVal->i;
+ return sqlite3VdbeIntValue((Mem*)pVal);
}
const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
return (const char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
/*
-** Convert the Mem to have representation MEM_Int only. All
-** prior representations are invalidated. NULL is converted into 0.
+** Return some kind of integer value which is the best we can do
+** at representing the value that *pMem describes as an integer.
+** If pMem is an integer, then the value is exact. If pMem is
+** a floating-point then the value returned is the integer part.
+** If pMem is a string or blob, then we make an attempt to convert
+** it into a integer and return that. If pMem is NULL, return 0.
+**
+** If pMem is a string, its encoding might be changed.
*/
-int sqlite3VdbeMemIntegerify(Mem *pMem){
+i64 sqlite3VdbeIntValue(Mem *pMem){
int flags = pMem->flags;
if( flags & MEM_Int ){
- /* Do nothing */
+ return pMem->i;
}else if( flags & MEM_Real ){
- pMem->i = (i64)pMem->r;
+ return (i64)pMem->r;
}else if( flags & (MEM_Str|MEM_Blob) ){
+ i64 value;
if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
|| sqlite3VdbeMemNulTerminate(pMem) ){
return SQLITE_NOMEM;
}
assert( pMem->z );
- sqlite3atoi64(pMem->z, &pMem->i);
+ sqlite3atoi64(pMem->z, &value);
+ return value;
}else{
- pMem->i = 0;
+ return 0;
}
- pMem->flags |= MEM_Int;
+}
+
+/*
+** Convert pMem to type integer. Invalidate any prior representations.
+*/
+int sqlite3VdbeMemIntegerify(Mem *pMem){
+ pMem->i = sqlite3VdbeIntValue(pMem);
+ sqlite3VdbeMemRelease(pMem);
+ pMem->flags = MEM_Int;
return SQLITE_OK;
}
/*
-** Add MEM_Real to the set of representations for pMem. Prior
-** prior representations other than MEM_Null retained. NULL is
-** converted into 0.0.
+** Return the best representation of pMem that we can get into a
+** double. If pMem is already a double or an integer, return its
+** value. If it is a string or blob, try to convert it to a double.
+** If it is a NULL, return 0.0.
*/
-int sqlite3VdbeMemRealify(Mem *pMem){
+double sqlite3VdbeRealValue(Mem *pMem){
if( pMem->flags & MEM_Real ){
- /* Do nothing */
- }else if( (pMem->flags & MEM_Int) && pMem->type!=SQLITE_TEXT ){
- pMem->r = pMem->i;
+ return pMem->r;
+ }else if( pMem->flags & MEM_Int ){
+ return (double)pMem->i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
|| sqlite3VdbeMemNulTerminate(pMem) ){
return SQLITE_NOMEM;
}
assert( pMem->z );
- pMem->r = sqlite3AtoF(pMem->z, 0);
+ return sqlite3AtoF(pMem->z, 0);
}else{
- pMem->r = 0.0;
+ return 0.0;
}
- pMem->flags |= MEM_Real;
+}
+
+/*
+** Convert pMem so that it is of type MEM_Real. Invalidate any
+** prior representations.
+*/
+int sqlite3VdbeMemRealify(Mem *pMem){
+ pMem->r = sqlite3VdbeRealValue(pMem);
+ sqlite3VdbeMemRelease(pMem);
+ pMem->flags = MEM_Real;
return SQLITE_OK;
}
/* MEM_Null excludes all other types */
assert( (pMem->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0
|| (pMem->flags&MEM_Null)==0 );
+ if( (pMem->flags & (MEM_Int|MEM_Real))==(MEM_Int|MEM_Real) ){
+ assert( pMem->r==pMem->i );
+ }
}
#endif
return (const void *)(pVal->z);
}
+/*
+** Create a new sqlite3_value object.
+*/
sqlite3_value* sqlite3ValueNew(){
Mem *p = sqliteMalloc(sizeof(*p));
if( p ){
return p;
}
+/*
+** Change the string value of an sqlite3_value object
+*/
void sqlite3ValueSetStr(
sqlite3_value *v,
int n,
if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel);
}
+/*
+** Free an sqlite3_value object
+*/
void sqlite3ValueFree(sqlite3_value *v){
if( !v ) return;
sqlite3ValueSetStr(v, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
sqliteFree(v);
}
+/*
+** Return the number of bytes in the sqlite3_value object assuming
+** that it uses the encoding "enc"
+*/
int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
Mem *p = (Mem*)pVal;
if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
# This file implements regression tests for SQLite library. The
# focus of this script testing the callback-free C/C++ API.
#
-# $Id: capi3.test,v 1.12 2004/06/19 03:33:57 danielk1977 Exp $
+# $Id: capi3.test,v 1.13 2004/06/27 01:56:33 drh Exp $
#
set testdir [file dirname $argv0]
} {SQLITE_OK}
finish_test
-
-