]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
More MEM changes in the vdbe.c. Still will not compile. (CVS 1469)
authordrh <drh@noemail.net>
Thu, 27 May 2004 01:53:56 +0000 (01:53 +0000)
committerdrh <drh@noemail.net>
Thu, 27 May 2004 01:53:56 +0000 (01:53 +0000)
FossilOrigin-Name: dbdd1a7f316e576d0611748ec63c9ef00d4c10db

13 files changed:
main.mk
manifest
manifest.uuid
src/sqliteInt.h
src/utf.c
src/util.c
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c
src/vdbeaux.c
src/vdbemem.c
test/bind.test
test/enc2.test

diff --git a/main.mk b/main.mk
index 00479d559633f23952d69fb3560428ed70270f3a..def00e9668eb1372aeae082d341be19fd86d3e96 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -58,8 +58,9 @@ LIBOBJ = attach.o auth.o btree.o build.o copy.o date.o delete.o \
          expr.o func.o hash.o insert.o \
          main.o opcodes.o os_mac.o os_unix.o os_win.o \
          pager.o parse.o pragma.o printf.o random.o \
-         select.o table.o tokenize.o trigger.o update.o util.o \
-         vacuum.o vdbe.o vdbeaux.o where.o tclsqlite.o utf.o legacy.o
+         select.o table.o tokenize.o trigger.o update.o util.o vacuum.o \
+         vdbe.o vdbeapi.o vdbeaux.o vdbemem.o \
+         where.o tclsqlite.o utf.o legacy.o
 
 # All of the source code files.
 #
@@ -102,7 +103,9 @@ SRC = \
   $(TOP)/src/vacuum.c \
   $(TOP)/src/vdbe.c \
   $(TOP)/src/vdbe.h \
+  $(TOP)/src/vdbeapi.c \
   $(TOP)/src/vdbeaux.c \
+  $(TOP)/src/vdbemem.c \
   $(TOP)/src/vdbeInt.h \
   $(TOP)/src/where.c
 
@@ -327,9 +330,15 @@ vacuum.o:  $(TOP)/src/vacuum.c $(HDR)
 vdbe.o:        $(TOP)/src/vdbe.c $(VDBEHDR)
        $(TCCX) -c $(TOP)/src/vdbe.c
 
+vdbeapi.o:     $(TOP)/src/vdbeapi.c $(VDBEHDR)
+       $(TCCX) -c $(TOP)/src/vdbeapi.c
+
 vdbeaux.o:     $(TOP)/src/vdbeaux.c $(VDBEHDR)
        $(TCCX) -c $(TOP)/src/vdbeaux.c
 
+vdbemem.o:     $(TOP)/src/vdbemem.c $(VDBEHDR)
+       $(TCCX) -c $(TOP)/src/vdbemem.c
+
 where.o:       $(TOP)/src/where.c $(HDR)
        $(TCCX) -c $(TOP)/src/where.c
 
index 8cd5d8f99a4a55a07e4dbf301d206848dfe9694b..a5e58214ccd1f59ece4b87b8ed4629ab919f39e3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C More\stest\scases\sfor\sthe\snew\squery\sAPI.\s(CVS\s1468)
-D 2004-05-27T01:49:51
+C More\sMEM\schanges\sin\sthe\svdbe.c.\s\sStill\swill\snot\scompile.\s(CVS\s1469)
+D 2004-05-27T01:53:56
 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -16,7 +16,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
 F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
-F main.mk bbbe8057c8fac1ec03af0a41f2fac5390dd30386
+F main.mk 466f12b816527d5bb1cf5dac4f23da77a02f99ad
 F publish.sh 1cd5c982388560fa91eedf6a338e210f713b35c8
 F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b
 F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
@@ -56,7 +56,7 @@ F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 F src/select.c e90e2a147273cdcdb1ee9e14574ab28f04382e63
 F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f
 F src/sqlite.h.in 68e165dc4dc2d477c95c76b9ede13eed5fbaabf4
-F src/sqliteInt.h 6b0d8d856c4af325eb5a00d1c32d89aacf432875
+F src/sqliteInt.h dbf4fd06e89cdab13f4f1129d76bf79a38ec2b39
 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
 F src/tclsqlite.c 86daf7bf6ba715bf0f0c7a47beb1d947a15cb868
 F src/test1.c ff7cc8729c320aec038e7d9d116bed9eabd642d0
@@ -67,15 +67,15 @@ F src/test5.c 9a1f15133f6955f067c5246e564723b5f23ff221
 F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
 F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f
 F src/update.c 96461bcf4e946697e83c09c77c7e61b545a2f66e
-F src/utf.c 1d38da85bffb928fb0d9f301e7db913a6df486ce
-F src/util.c 4c0adcbc9ce6678dd046931253e45d623c6d279f
+F src/utf.c 73d70f2764cb34b072e2d7b0f0c23c389cfc1baa
+F src/util.c caef24dcf3d7dfb7ac747ed36c080d95457fac71
 F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad
-F src/vdbe.c 4419d3b7e4d56b0c1d973ebf4de40ee5045e612e
+F src/vdbe.c 06f02181b5fe39b99cb98714bf36e95005e03ef7
 F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb
-F src/vdbeInt.h 8647afb4c3889c827a4c0aa310a54c5ec0ebc934
-F src/vdbeapi.c 36d4c78bc765dc89cac07ff975b26256e0ac90fc
-F src/vdbeaux.c 677317be4021eadce96365b16d9deeda9e565bef
-F src/vdbemem.c c92c41c80c333b3cd405a08ebfd014d02a9f7b8c
+F src/vdbeInt.h d62f70eb935bf056d9eb7dfb9783393274685e1d
+F src/vdbeapi.c 56b7de7af5800fbbf79fd953da95ee61c379a387
+F src/vdbeaux.c de2d82e4cf5815595ae74bd5f663042428efb6a8
+F src/vdbemem.c 3474db5cdb19a8aa1b1e8e78189e1e8cda2394aa
 F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
@@ -83,7 +83,7 @@ F test/attach2.test 5472d442bb2ef1ee587e0ae7472bb68b52509a38
 F test/auth.test 5c4d95cdaf539c0c236e20ce1f71a93e7dde9185
 F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81
 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
-F test/bind.test 44097e9a885ac851934c2e9b74d2fec36659bca5
+F test/bind.test ef1efd5cf63b27c11acda9a1c0c7403960f12400
 F test/btree.test 08e4093c78d2bc1d54e27266f8d17fed14751125
 F test/btree2.test aa4a6d05b1ea90b1acaf83ba89039dd302a88635
 F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
@@ -97,7 +97,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
 F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d
 F test/delete.test 92256384f1801760180ded129f7427884cf28886
 F test/enc.test a55481d45ff493804e8d88357feb4642fc50a6b2
-F test/enc2.test f80bcf14a286f34e54378b9b044c5d93b7679bc1
+F test/enc2.test 669f46b4e298a22fb515cb52c55eb8dca57d8b4a
 F test/expr.test 8b62f3fcac64fbd5c3d43d7a7984245743dcbe65
 F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7
 F test/format3.test 149cc166c97923fa60def047e90dd3fb32bba916
@@ -205,7 +205,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P d72adf0c522b442d5e1663862bdd639c282d4495
-R 2ba0c044593753a501ecb5b9d1ce6722
-U danielk1977
-Z 64c9fdf3b1584f065ec0b7238e3a9f4f
+P 74097ecdb0b1e0eec143c5a3f8ca2f0d63d6f38d
+R 98aa4ae2a65faf4f8c17b075955c2246
+U drh
+Z eb27f7bb480c5083f24dd280c1f9cf51
index e14ac09a849cc5e407b6acd3966354af5617c93f..698e80ef2bb65799ea5f548848d5d17a38f283a7 100644 (file)
@@ -1 +1 @@
-74097ecdb0b1e0eec143c5a3f8ca2f0d63d6f38d
\ No newline at end of file
+dbdd1a7f316e576d0611748ec63c9ef00d4c10db
\ No newline at end of file
index e23710e78ccbbbc01cab676abbd39b0f184f228d..4b4b825f9449f2a7f59136fa1c1ba7a0a8f6daec 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.253 2004/05/26 16:54:45 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.254 2004/05/27 01:53:56 drh Exp $
 */
 #include "config.h"
 #include "sqlite.h"
@@ -1347,7 +1347,7 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2);
 char const *sqlite3AffinityString(char affinity);
 int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
 char sqlite3ExprAffinity(Expr *pExpr);
-int sqlite3atoi64(const char*, i64*, u8);
+int sqlite3atoi64(const char*, i64*);
 void sqlite3Error(sqlite *, int, const char*,...);
 int sqlite3utfTranslate(const void *, int , u8 , void **, int *, u8);
 u8 sqlite3UtfReadBom(const void *zData, int nData);
index 6f9dff106c848e17802f248e0fbc2e2d2001d1f7..b8e11d8da05a4768c104985e6498fbd19245229e 100644 (file)
--- a/src/utf.c
+++ b/src/utf.c
@@ -12,7 +12,7 @@
 ** This file contains routines used to translate between UTF-8, 
 ** UTF-16, UTF-16BE, and UTF-16LE.
 **
-** $Id: utf.c,v 1.10 2004/05/24 12:39:02 danielk1977 Exp $
+** $Id: utf.c,v 1.11 2004/05/27 01:53:56 drh Exp $
 **
 ** Notes on UTF-8:
 **
@@ -579,12 +579,10 @@ void sqlite3utf16to16be(void *pData, int N){
 ** result is returned in dynamically allocated memory.
 */
 int sqlite3utfTranslate(
-  const void *zData,
-  int nData,
-  u8 enc1,
-  void **zOut,
-  int *nOut,
-  u8 enc2
+  const void *zData, int nData,  /* Input string */
+  u8 enc1,                       /* Encoding of zData */
+  void **zOut, int *nOut,        /* Output string */
+  u8 enc2                        /* Desired encoding of output */
 ){
   assert( enc1==TEXT_Utf8 || enc1==TEXT_Utf16le || enc1==TEXT_Utf16be );
   assert( enc2==TEXT_Utf8 || enc2==TEXT_Utf16le || enc2==TEXT_Utf16be );
@@ -608,5 +606,3 @@ int sqlite3utfTranslate(
   }
   return SQLITE_OK;
 }
-
-
index b3744e23c77e6371daa75ff3bd929e4dd60d83ab..0d1a5b974811f25bebb3128dcf874911d6946507 100644 (file)
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.88 2004/05/24 07:04:26 danielk1977 Exp $
+** $Id: util.c,v 1.89 2004/05/27 01:53:56 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -665,27 +665,23 @@ double sqlite3AtoF(const char *z, const char **pzEnd){
 ** 32-bit numbers.  At that time, it was much faster than the
 ** atoi() library routine in RedHat 7.2.
 */
-int sqlite3atoi64(const char *zNum, i64 *pNum, u8 enc){
+int sqlite3atoi64(const char *zNum, i64 *pNum){
   i64 v = 0;
   int neg;
   int i, c;
-  int incr = (enc==TEXT_Utf8?1:2);
-  if( enc==TEXT_Utf16be ) zNum++;
   if( *zNum=='-' ){
     neg = 1;
-    zNum += incr;
+    zNum++;
   }else if( *zNum=='+' ){
     neg = 0;
-    zNum += incr;
+    zNum++;
   }else{
     neg = 0;
   }
-  for(i=0; (c=zNum[i])>='0' && c<='9'; i += incr){
+  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
     v = v*10 + c - '0';
   }
   *pNum = neg ? -v : v;
-
-  /* FIX ME: Handle overflow of strings in UTF-16 here */
   return c==0 && i>0 && 
       (i<19 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0));
 }
index c5f75a9daa63bb2d7d96619627772276668cc411..dbcab5066b98c7a80e72f6f78644a9d9d50cde2f 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.336 2004/05/26 23:25:31 drh Exp $
+** $Id: vdbe.c,v 1.337 2004/05/27 01:53:56 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -69,105 +69,18 @@ int sqlite3_search_count = 0;
 */
 int sqlite3_interrupt_count = 0;
 
-/*
-** This macro takes a single parameter, a pointer to a Mem structure.
-** It returns the string encoding for the Mem structure, one of TEXT_Utf8
-** TEXT_Utf16le or TEXT_Utf16be.
-*/
-#define MemEnc(p) ( \
-   ((p)->flags&MEM_Utf16le)?TEXT_Utf16le: \
-       ((p)->flags&MEM_Utf16be)?TEXT_Utf16be:TEXT_Utf8) )
-
 /*
 ** Release the memory associated with the given stack level.  This
 ** leaves the Mem.flags field in an inconsistent state.
 */
 #define Release(P) if((P)->flags&MEM_Dyn){ sqliteFree((P)->z); }
 
-/*
-** Parmameter "flags" is the value of the flags for a string Mem object.
-** Return one of TEXT_Utf8, TEXT_Utf16le or TEXT_Utf16be, depending
-** on the encoding indicated by the flags value.
-*/
-static u8 flagsToEnc(int flags){
-  if( flags&MEM_Utf8 ){
-    assert( !(flags&(MEM_Utf16be|MEM_Utf16le)) );
-    return TEXT_Utf8;
-  }
-  if( flags&MEM_Utf16le ){
-    assert( !(flags&(MEM_Utf8|MEM_Utf16be)) );
-    return TEXT_Utf16le;
-  }
-  assert( flags&MEM_Utf16be );
-  assert( !(flags&(MEM_Utf8|MEM_Utf16le)) );
-  return TEXT_Utf16be;
-}
-
-/*
-** Parameter "enc" is one of TEXT_Utf8, TEXT_Utf16le or TEXT_Utf16be.
-** Return the corresponding MEM_Utf* value.
-*/
-static int encToFlags(u8 enc){
-  switch( enc ){
-    case TEXT_Utf8:   return MEM_Utf8;
-    case TEXT_Utf16be: return MEM_Utf16be;
-    case TEXT_Utf16le: return MEM_Utf16le;
-  }
-  assert(0);
-}
-
-/*
-** Set the encoding flags of memory cell "pMem" to the correct values
-** for the database encoding "enc" (one of TEXT_Utf8, TEXT_Utf16le or
-** TEXT_Utf16be).
-*/
-#define SetEncodingFlags(pMem, enc) ((pMem)->flags = \
-((pMem->flags & ~(MEM_Utf8|MEM_Utf16le|MEM_Utf16be))) | encToFlags(enc))
-static int SetEncoding(Mem*, int);
-
 /*
 ** Convert the given stack entity into a string if it isn't one
 ** already. Return non-zero if a malloc() fails.
 */
 #define Stringify(P, enc) \
-(!((P)->flags&(MEM_Str|MEM_Blob)) && hardStringify(P, enc))
-static int hardStringify(Mem *pStack, u8 enc){
-  int rc = SQLITE_OK;
-  int fg = pStack->flags;
-
-  assert( !(fg&(MEM_Str|MEM_Blob)) );
-  assert( fg&(MEM_Int|MEM_Real|MEM_Null) );
-
-  if( fg & MEM_Null ){      
-    /* A NULL value is converted to a zero length string */
-    pStack->zShort[0] = 0;
-    pStack->zShort[1] = 0;
-    pStack->flags = MEM_Str | MEM_Short | MEM_Term;
-    pStack->z = pStack->zShort;
-    pStack->n = (enc==TEXT_Utf8?1:2);
-  }else{
-    /* 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.
-    ** 
-    ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
-    */
-    if( fg & MEM_Real ){
-      sqlite3_snprintf(NBFS, pStack->zShort, "%.15g", pStack->r);
-    }else if( fg & MEM_Int ){
-      sqlite3_snprintf(NBFS, pStack->zShort, "%lld", pStack->i);
-    }
-    pStack->n = strlen(pStack->zShort) + 1;
-    pStack->z = pStack->zShort;
-    pStack->flags = MEM_Str | MEM_Short | MEM_Term;
-
-    /* Flip the string to UTF-16 if required */
-    SetEncodingFlags(pStack, TEXT_Utf8);
-    rc = SetEncoding(pStack, encToFlags(enc)|MEM_Term);
-  }
-
-  return rc;
-}
+      (!((P)->flags&(MEM_Str|MEM_Blob)) && sqlite3VdbeMemStringify(P,enc))
 
 /*
 ** Convert the given stack entity into a string that has been obtained
@@ -176,22 +89,8 @@ static int hardStringify(Mem *pStack, u8 enc){
 ** will fit but this routine always mallocs for space.
 ** Return non-zero if we run out of memory.
 */
-#define Dynamicify(P, enc) \
-(((P)->flags & MEM_Dyn)==0 ? hardDynamicify(P, enc):0)
-static int hardDynamicify(Mem *pStack, u8 enc){
-  int fg = pStack->flags;
-  char *z;
-  if( (fg & MEM_Str)==0 ){
-    hardStringify(pStack, enc);
-  }
-  assert( (fg & MEM_Dyn)==0 );
-  z = sqliteMallocRaw( pStack->n );
-  if( z==0 ) return 1;
-  memcpy(z, pStack->z, pStack->n);
-  pStack->z = z;
-  pStack->flags |= MEM_Dyn;
-  return 0;
-}
+#define Dynamicify(P,enc) sqlite3VdbeMemDynamicify(P)
+
 
 /*
 ** An ephemeral string value (signified by the MEM_Ephem flag) contains
@@ -205,18 +104,8 @@ static int hardDynamicify(Mem *pStack, u8 enc){
 ** converts an MEM_Ephem string into an MEM_Dyn string.
 */
 #define Deephemeralize(P) \
-   if( ((P)->flags&MEM_Ephem)!=0 && hardDeephem(P) ){ goto no_mem;}
-static int hardDeephem(Mem *pStack){
-  char *z;
-  assert( (pStack->flags & MEM_Ephem)!=0 );
-  z = sqliteMallocRaw( pStack->n );
-  if( z==0 ) return 1;
-  memcpy(z, pStack->z, pStack->n);
-  pStack->z = z;
-  pStack->flags &= ~MEM_Ephem;
-  pStack->flags |= MEM_Dyn;
-  return 0;
-}
+   if( ((P)->flags&MEM_Ephem)!=0 \
+       && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}
 
 /*
 ** Convert the given stack entity into a integer if it isn't one
@@ -226,19 +115,7 @@ static int hardDeephem(Mem *pStack){
 ** NULLs are converted into 0.
 */
 #define Integerify(P, enc) \
-if(((P)->flags&MEM_Int)==0){ hardIntegerify(P, enc); }
-static void hardIntegerify(Mem *pStack, u8 enc){
-  pStack->i = 0;
-  if( pStack->flags & MEM_Real ){
-    pStack->i = (int)pStack->r;
-    Release(pStack);
-  }else if( pStack->flags & MEM_Str ){
-    if( pStack->z ){
-      sqlite3atoi64(pStack->z, &pStack->i, enc);
-    }
-  }
-  pStack->flags = MEM_Int;
-}
+    if((P)->flags!=MEM_Int){ sqlite3VdbeMemIntegerify(P); }
 
 /*
 ** Get a valid Real representation for the given stack element.
@@ -246,21 +123,8 @@ static void hardIntegerify(Mem *pStack, u8 enc){
 ** Any prior string or integer representation is retained.
 ** NULLs are converted into 0.0.
 */
-#define Realify(P,enc) if(((P)->flags&MEM_Real)==0){ hardRealify(P,enc); }
-static void hardRealify(Mem *pStack, u8 enc){
-  if( pStack->flags & MEM_Str ){
-    SetEncodingFlags(pStack, enc);
-    SetEncoding(pStack, MEM_Utf8|MEM_Term);
-    pStack->r = sqlite3AtoF(pStack->z, 0);
-  }else if( pStack->flags & MEM_Int ){
-    pStack->r = pStack->i;
-  }else{
-    pStack->r = 0.0;
-  }
-/*  pStack->flags |= MEM_Real; */
-  pStack->flags = MEM_Real;
-}
-
+#define Realify(P,enc) \
+    if(((P)->flags&MEM_Real)==0){ sqlite3VdbeMemRealify(P); }
 
 
 /*
@@ -1158,29 +1022,26 @@ case OP_Concat: {
   int nField;
   int i, j;
   Mem *pTerm;
-  Mem zSep; /* Memory cell containing the seperator string, if any */
-  int termLen;  /* Bytes in the terminator character for this encoding */
-
-  termLen = (db->enc==TEXT_Utf8?1:2);
+  Mem mSep;     /* Memory cell containing the seperator string, if any */
 
   /* FIX ME: Eventually, P3 will be in database native encoding. But for
   ** now it is always UTF-8. So set up zSep to hold the native encoding of
   ** P3.
   */
   if( pOp->p3 ){
-    zSep.z = pOp->p3;
-    zSep.n = strlen(zSep.z)+1;
-    zSep.flags = MEM_Str|MEM_Static|MEM_Utf8|MEM_Term;
-    SetEncoding(&zSep, encToFlags(db->enc)|MEM_Term);
+    mSep.z = pOp->p3;
+    mSep.n = strlen(mSep.z);
+    mSep.flags = MEM_Str|MEM_Static|MEM_Term;
+    mSep.enc = TEXT_Utf8;
+    sqlite3VdbeChangeEncoding(&mSep, db->enc);
   }else{
-    zSep.flags = MEM_Null;
-    zSep.n = 0;
+    mSep.flags = MEM_Null;
   }
 
   /* Loop through the stack elements to see how long the result will be. */
   nField = pOp->p1;
   pTerm = &pTos[1-nField];
-  nByte = termLen + (nField-1)*(zSep.n - ((zSep.flags&MEM_Term)?termLen:0));
+  nByte = (nField-1)*mSep.n;
   for(i=0; i<nField; i++, pTerm++){
     assert( pOp->p2==0 || (pTerm->flags&MEM_Str) );
     if( pTerm->flags&MEM_Null ){
@@ -1188,7 +1049,7 @@ case OP_Concat: {
       break;
     }
     Stringify(pTerm, db->enc);
-    nByte += (pTerm->n - ((pTerm->flags&MEM_Term)?termLen:0));
+    nByte += pTerm->n;
   }
 
   if( nByte<0 ){
@@ -1205,33 +1066,32 @@ case OP_Concat: {
     /* Otherwise malloc() space for the result and concatenate all the
     ** stack values.
     */
-    zNew = sqliteMallocRaw( nByte );
+    zNew = sqliteMallocRaw( nByte+2 );
     if( zNew==0 ) goto no_mem;
     j = 0;
     pTerm = &pTos[1-nField];
     for(i=j=0; i<nField; i++, pTerm++){
-      int n = pTerm->n-((pTerm->flags&MEM_Term)?termLen:0);
+      int n = pTerm->n;
       assert( pTerm->flags & MEM_Str );
       memcpy(&zNew[j], pTerm->z, n);
       j += n;
-      if( i<nField-1 && !(zSep.flags|MEM_Null) ){
-        n = zSep.n-((zSep.flags&MEM_Term)?termLen:0);
-        memcpy(&zNew[j], zSep.z, n);
-        j += n;
+      if( i<nField-1 && !(mSep.flags|MEM_Null) ){
+        memcpy(&zNew[j], mSep.z, mSep.n);
+        j += mSep.n;
       }
     }
-    zNew[j++] = 0;
-    if( termLen==2 ){
-      zNew[j++] = 0;
-    }
-    assert( j==nByte );
+    zNew[j] = 0;
+    zNew[j+1] = 0;
+    assert( j==nByte-1 );
 
     if( pOp->p2==0 ){
       popStack(&pTos, nField);
     }
     pTos++;
-    pTos->n = nByte;
-    pTos->flags = MEM_Str|MEM_Dyn|MEM_Term|encToFlags(db->enc);
+    pTos->n = j;
+    pTos->flags = MEM_Str|MEM_Dyn|MEM_Term
+    pTos->enc = db->enc;
+    pTos->type = SQLITE3_TEXT;
     pTos->z = zNew;
   }
   break;
@@ -1553,12 +1413,16 @@ case OP_MustBeInt: {
     pTos->i = i;
   }else if( pTos->flags & MEM_Str ){
     i64 v;
-    if( !sqlite3atoi64(pTos->z, &v, db->enc) ){
+    if( sqlite3VdbeChangeEncoding(pTos, TEXT_Utf8)
+       || sqlite3VdbeNulTerminate(pTos) ){
+      goto no_mem;
+    }
+    if( !sqlite3atoi64(pTos->z, &v) ){
       double r;
-      if( !sqlite3IsNumber(pTos->z, 0, db->enc) ){
+      if( !sqlite3IsNumber(pTos->z, 0, TEXT_Utf8) ){
         goto mismatch;
       }
-      Realify(pTos, db->enc);
+      Realify(pTos, TEXT_Utf8);
       v = (int)pTos->r;
       r = (double)v;
       if( r!=pTos->r ){
@@ -1571,6 +1435,7 @@ case OP_MustBeInt: {
   }
   Release(pTos);
   pTos->flags = MEM_Int;
+  pTos->type = SQLITE3_INTEGER;
   break;
 
 mismatch:
@@ -4385,11 +4250,9 @@ case OP_SortNext: {
     pTos++;
     pTos->z = pSorter->pData;
     pTos->n = pSorter->nData;
-    /* FIX ME: I don't understand this. What does the sorter return? 
-    ** I thought it would be the commented out flags.
-    */
-    /* pTos->flags = MEM_Blob|MEM_Dyn; */
-    pTos->flags = MEM_Str|MEM_Dyn|MEM_Utf8|MEM_Term;
+    pTos->flags = MEM_Blob|MEM_Dyn|MEM_Term;
+    pTos->enc = 0;
+    pTos->type = SQLITE3_BLOB;
     sqliteFree(pSorter->zKey);
     sqliteFree(pSorter);
   }else{
index 599cb341fd3f0133ceee3502c167bc70cdcbdf2d..9dc55c24b57f73298e2c22e036f2076c0ed2a361 100644 (file)
@@ -356,3 +356,10 @@ int sqlite3VdbeSetEncoding(Mem *, u8);
 int sqlite3VdbeMemCopy(Mem*, const Mem*);
 int sqlite3VdbeMemNulTerminate(Mem *);
 int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, int);
+int sqlite3VdbeMemSetInt64(Mem*, long long int);
+int sqlite3VdbeMemSetDouble(Mem*, double);
+int sqlite3VdbeMemMakeWriteable(Mem*);
+int sqlite3VdbeMemDynamicify(Mem*);
+int sqlite3VdbeMemStringify(Mem*);
+int sqlite3VdbeMemIntegerify(Mem*);
+int sqlite3VdbeMemRealify(Mem*);
index 1a5e86c65fa6437cf2e42e379b4db0c2be1930ca..d21eb17308ba3514a39b0244eff70ac6db86d031 100644 (file)
@@ -198,6 +198,50 @@ int sqlite3_step(sqlite3_stmt *pStmt){
   return rc;
 }
 
+/*
+** Extract the user data from a sqlite3_context structure and return a
+** pointer to it.
+*/
+void *sqlite3_user_data(sqlite3_context *p){
+  assert( p && p->pFunc );
+  return p->pFunc->pUserData;
+}
+
+/*
+** Allocate or return the aggregate context for a user function.  A new
+** context is allocated on the first call.  Subsequent calls return the
+** same context that was returned on prior calls.
+**
+** This routine is defined here in vdbe.c because it depends on knowing
+** the internals of the sqlite3_context structure which is only defined in
+** this source file.
+*/
+void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
+  assert( p && p->pFunc && p->pFunc->xStep );
+  if( p->pAgg==0 ){
+    if( nByte<=NBFS ){
+      p->pAgg = (void*)p->s.z;
+      memset(p->pAgg, 0, nByte);
+    }else{
+      p->pAgg = sqliteMalloc( nByte );
+    }
+  }
+  return p->pAgg;
+}
+
+/*
+** Return the number of times the Step function of a aggregate has been 
+** called.
+**
+** This routine is defined here in vdbe.c because it depends on knowing
+** the internals of the sqlite3_context structure which is only defined in
+** this source file.
+*/
+int sqlite3_aggregate_count(sqlite3_context *p){
+  assert( p && p->pFunc && p->pFunc->xStep );
+  return p->cnt;
+}
+
 /*
 ** Return the number of columns in the result set for the statement pStmt.
 */
index fd72c25ba59d87645cd51824e186d9e329ea8c0d..256ec2b3d012b3b3a194a1af4aaf5ee85b3fa493 100644 (file)
@@ -109,7 +109,7 @@ int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
 /*
 ** Add an opcode that includes the p3 value.
 */
-int sqlite3VdbeOp3(Vdbe *p, int op, int p1, int p2, const char *zP3, int p3type){
+int sqlite3VdbeOp3(Vdbe *p, int op, int p1, int p2, const char *zP3,int p3type){
   int addr = sqlite3VdbeAddOp(p, op, p1, p2);
   sqlite3VdbeChangeP3(p, addr, zP3, p3type);
   return addr;
@@ -424,50 +424,6 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
   return &p->aOp[addr];
 }
 
-/*
-** Extract the user data from a sqlite3_context structure and return a
-** pointer to it.
-*/
-void *sqlite3_user_data(sqlite3_context *p){
-  assert( p && p->pFunc );
-  return p->pFunc->pUserData;
-}
-
-/*
-** Allocate or return the aggregate context for a user function.  A new
-** context is allocated on the first call.  Subsequent calls return the
-** same context that was returned on prior calls.
-**
-** This routine is defined here in vdbe.c because it depends on knowing
-** the internals of the sqlite3_context structure which is only defined in
-** this source file.
-*/
-void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
-  assert( p && p->pFunc && p->pFunc->xStep );
-  if( p->pAgg==0 ){
-    if( nByte<=NBFS ){
-      p->pAgg = (void*)p->s.z;
-      memset(p->pAgg, 0, nByte);
-    }else{
-      p->pAgg = sqliteMalloc( nByte );
-    }
-  }
-  return p->pAgg;
-}
-
-/*
-** Return the number of times the Step function of a aggregate has been 
-** called.
-**
-** This routine is defined here in vdbe.c because it depends on knowing
-** the internals of the sqlite3_context structure which is only defined in
-** this source file.
-*/
-int sqlite3_aggregate_count(sqlite3_context *p){
-  assert( p && p->pFunc && p->pFunc->xStep );
-  return p->cnt;
-}
-
 /*
 ** Compute a string that describes the P3 parameter for an opcode.
 ** Use zTemp for any required temporary buffer space.
@@ -613,23 +569,36 @@ int sqlite3VdbeList(
     sqlite3SetString(&p->zErrMsg, sqlite3_error_string(p->rc), (char*)0);
   }else{
     Op *pOp = &p->aOp[i];
-    p->aStack[0].flags = MEM_Int;
-    p->aStack[0].i = i;                                /* Program counter */
-    p->aStack[1].flags = MEM_Static|MEM_Str|MEM_Utf8|MEM_Term;
-    p->aStack[1].z = sqlite3OpcodeNames[pOp->opcode];  /* Opcode */
-    p->aStack[2].flags = MEM_Int;
-    p->aStack[2].i = pOp->p1;                          /* P1 */
-    p->aStack[3].flags = MEM_Int;
-    p->aStack[3].i = pOp->p2;                          /* P2 */
-    p->aStack[4].flags = MEM_Str|MEM_Utf8|MEM_Term;    /* P3 */
-    p->aStack[4].z = displayP3(pOp, p->aStack[4].zShort, NBFS);
-    if( p->aStack[4].z==p->aStack[4].zShort ){
-      p->aStack[4].flags |= MEM_Short;
-    }else{
-      p->aStack[4].flags |= MEM_Static;
-    }
+    Mem *pMem = p->aStack;
+    pMem->flags = MEM_Int;
+    pMem->type = SQLITE3_INT;
+    pMem->i = i;                                /* Program counter */
+    pMem++;
+
+    pMem->flags = MEM_Static|MEM_Str|MEM_Term;
+    pMem->z = sqlite3OpcodeNames[pOp->opcode];  /* Opcode */
+    pMem->n = strlen(pMem->z);
+    pMem->type = SQLITE3_TEXT;
+    pMem->enc = TEXT_Utf8;
+    pMem++;
+
+    pMem->flags = MEM_Int;
+    pMem->i = pOp->p1;                          /* P1 */
+    pMem->type = SQLITE3_INT;
+    pMem++;
+
+    pMem->flags = MEM_Int;
+    pMem->i = pOp->p2;                          /* P2 */
+    pMem->type = SQLITE_INT;
+    pMem++;
+
+    pMem->flags = MEM_Short|MEM_Str|MEM_Term;   /* P3 */
+    pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort));
+    pMem->type = SQLITE_TEXT;
+    pMem->enc = TEXT_Utf8;
+
     p->nResColumn = 5;
-    p->pTos = &p->aStack[4];
+    p->pTos = pMem;
     p->rc = SQLITE_OK;
     p->resOnStack = 1;
     rc = SQLITE_ROW;
@@ -1184,15 +1153,6 @@ u64 sqlite3VdbeSerialType(Mem *pMem){
   if( flags&MEM_Str ){
     int n = pMem->n;
     assert( n>=0 );
-    if( pMem->flags&MEM_Term ){
-      /* If the nul terminated flag is set we have to subtract something
-      ** from the serial-type. Depending on the encoding there could be
-      ** one or two 0x00 bytes at the end of the string. Check for these
-      ** and subtract 2 from serial_
-      */
-      if( n>0 && !pMem->z[n-1] ) n--;
-      if( n>0 && !pMem->z[n-1] ) n--;
-    }
     return ((n*2) + 13);
   }
   if( flags&MEM_Blob ){
@@ -1279,6 +1239,7 @@ int sqlite3VdbeSerialGet(
   /* NULL */
   if( serial_type==6 ){
     pMem->flags = MEM_Null;
+    pMem->type = SQLITE3_NULL;
     return 0;
   }
  
@@ -1297,9 +1258,11 @@ int sqlite3VdbeSerialGet(
     if( serial_type==5 ){
       pMem->flags = MEM_Real;
       pMem->r = *(double*)&v;
+      pMem->type = SQLITE3_FLOAT;
     }else{
       pMem->flags = MEM_Int;
       pMem->i = *(i64*)&v;
+      pMem->type = SQLITE3_INTEGER;
     }
     return len;
   }
@@ -1308,136 +1271,16 @@ int sqlite3VdbeSerialGet(
   assert( serial_type>=12 );
   len = sqlite3VdbeSerialTypeLen(serial_type);
   if( serial_type&0x01 ){
-    switch( enc ){
-      case TEXT_Utf8:
-        pMem->flags = MEM_Str|MEM_Utf8|MEM_Term;
-        break;
-      case TEXT_Utf16le:
-        pMem->flags = MEM_Str|MEM_Utf16le|MEM_Term;
-        break;
-      case TEXT_Utf16be:
-        pMem->flags = MEM_Str|MEM_Utf16be|MEM_Term;
-        break;
-      assert(0);
-    }
-    pMem->n = len+(enc==TEXT_Utf8?1:2);
-  }else{
-    pMem->flags = MEM_Blob;
+    pMem->flags = MEM_Str | MEM_Ephem;
     pMem->n = len;
-  }
-
-  if( (pMem->n)>NBFS ){
-    pMem->z = sqliteMallocRaw( pMem->n );
-    if( !pMem->z ){
-      return -1;
-    }
-    pMem->flags |= MEM_Dyn;
   }else{
-    pMem->z = pMem->zShort;
-    pMem->flags |= MEM_Short;
-  }
-
-  memcpy(pMem->z, buf, len); 
-  if( pMem->flags&MEM_Str ){
-    pMem->z[len] = '\0';
-    if( enc!=TEXT_Utf8 ){
-      pMem->z[len+1] = '\0';
-    }
+    pMem->flags = MEM_Blob | MEM_Ephem;
+    pMem->n = len;
   }
-
+  sqlite3VdbeMemMakeWriteable(pMem);
   return len;
 }
 
-/*
-** Compare the values contained by the two memory cells, returning
-** negative, zero or positive if pMem1 is less than, equal to, or greater
-** than pMem2. Sorting order is NULL's first, followed by numbers (integers
-** and reals) sorted numerically, followed by text ordered by the collating
-** sequence pColl and finally blob's ordered by memcmp().
-**
-** Two NULL values are considered equal by this function.
-*/
-int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
-  int rc;
-  int f1, f2;
-  int combined_flags;
-
-  /* Interchange pMem1 and pMem2 if the collating sequence specifies
-  ** DESC order.
-  */
-  f1 = pMem1->flags;
-  f2 = pMem2->flags;
-  combined_flags = f1|f2;
-  /* If one value is NULL, it is less than the other. If both values
-  ** are NULL, return 0.
-  */
-  if( combined_flags&MEM_Null ){
-    return (f2&MEM_Null) - (f1&MEM_Null);
-  }
-
-  /* If one value is a number and the other is not, the number is less.
-  ** If both are numbers, compare as reals if one is a real, or as integers
-  ** if both values are integers.
-  */
-  if( combined_flags&(MEM_Int|MEM_Real) ){
-    if( !(f1&(MEM_Int|MEM_Real)) ){
-      return 1;
-    }
-    if( !(f2&(MEM_Int|MEM_Real)) ){
-      return -1;
-    }
-    if( (f1 & f2 & MEM_Int)==0 ){
-      double r1, r2;
-      if( (f1&MEM_Real)==0 ){
-        r1 = pMem1->i;
-      }else{
-        r1 = pMem1->r;
-      }
-      if( (f2&MEM_Real)==0 ){
-        r2 = pMem2->i;
-      }else{
-        r2 = pMem2->r;
-      }
-      if( r1<r2 ) return -1;
-      if( r1>r2 ) return 1;
-      return 0;
-    }else{
-      assert( f1&MEM_Int );
-      assert( f2&MEM_Int );
-      if( pMem1->i < pMem2->i ) return -1;
-      if( pMem1->i > pMem2->i ) return 1;
-      return 0;
-    }
-  }
-
-  /* If one value is a string and the other is a blob, the string is less.
-  ** If both are strings, compare using the collating functions.
-  */
-  if( combined_flags&MEM_Str ){
-    if( (f1 & MEM_Str)==0 ){
-      return 1;
-    }
-    if( (f2 & MEM_Str)==0 ){
-      return -1;
-    }
-    if( pColl && pColl->xCmp ){
-      return pColl->xCmp(pColl->pUser, pMem1->n, pMem1->z, pMem2->n, pMem2->z);
-    }else{
-      /* If no collating sequence is defined, fall through into the
-      ** blob case below and use memcmp() for the comparison. */
-    }
-  }
-  /* Both values must be blobs.  Compare using memcmp().
-  */
-  rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
-  if( rc==0 ){
-    rc = pMem1->n - pMem2->n;
-  }
-  return rc;
-}
-
 /*
 ** The following is the comparison function for (non-integer)
 ** keys in the btrees.  This function returns negative, zero, or
@@ -1703,232 +1546,3 @@ int sqlite3VdbeIdxKeyCompare(
   }
   return SQLITE_OK;
 }
-
-/*
-** Parameter "enc" is one of TEXT_Utf8, TEXT_Utf16le or TEXT_Utf16be.
-** Return the corresponding MEM_Utf* value.
-*/
-static int encToFlags(u8 enc){
-  switch( enc ){
-    case TEXT_Utf8: return MEM_Utf8;
-    case TEXT_Utf16be: return MEM_Utf16be;
-    case TEXT_Utf16le: return MEM_Utf16le;
-  }
-  assert(0);
-}
-static u8 flagsToEnc(int flags){
-  switch( flags&(MEM_Utf8|MEM_Utf16be|MEM_Utf16le) ){
-    case MEM_Utf8: return TEXT_Utf8;
-    case MEM_Utf16le: return TEXT_Utf16le;
-    case MEM_Utf16be: return TEXT_Utf16be;
-  }
-  return 0;
-}
-
-/*
-** Delete any previous value and set the value stored in *pMem to NULL.
-*/
-void sqlite3VdbeMemSetNull(Mem *pMem){
-  if( pMem->flags&MEM_Dyn ){
-    sqliteFree(pMem->z);
-  }
-  pMem->flags = MEM_Null;
-}
-
-/*
-** Delete any previous value and set the value stored in *pMem to val,
-** manifest type INTEGER.
-*/
-void sqlite3VdbeMemSetInt(Mem *pMem, i64 val){
-  MemSetNull(pMem);
-  pMem->i = val;
-  pMem->flags = MEM_Int;
-}
-
-/*
-** Delete any previous value and set the value stored in *pMem to val,
-** manifest type REAL.
-*/
-void sqlite3VdbeMemSetReal(Mem *pMem, double val){
-  MemSetNull(pMem);
-  pMem->r = val;
-  pMem->flags = MEM_Real;
-}
-
-/*
-** Copy the contents of memory cell pFrom into pTo.
-*/
-int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
-  if( pTo->flags&MEM_Dyn ){
-    sqliteFree(pTo->z);
-  }
-
-  memcpy(pTo, pFrom, sizeof(*pFrom));
-  if( pTo->flags&MEM_Short ){
-    pTo->z = pTo->zShort;
-  }
-  else if( pTo->flags&(MEM_Ephem|MEM_Dyn) ){
-    pTo->flags = pTo->flags&(~(MEM_Static|MEM_Ephem|MEM_Short|MEM_Dyn));
-    if( pTo->n>NBFS ){
-      pTo->z = sqliteMalloc(pTo->n);
-      if( !pTo->z ) return SQLITE_NOMEM;
-      pTo->flags |= MEM_Dyn;
-    }else{
-      pTo->z = pTo->zShort;
-      pTo->flags |= MEM_Short;
-    }
-    memcpy(pTo->z, pFrom->z, pTo->n);
-  }
-  return SQLITE_OK;
-}
-
-int sqlite3VdbeMemSetStr(
-  Mem *pMem,          /* Memory cell to set to string value */
-  const char *z,      /* String pointer */
-  int n,              /* Bytes in string, or negative */
-  u8 enc,             /* Encoding of z */
-  int eCopy           /* True if this function should make a copy of z */
-){
-  Mem tmp;
-
-  if( !z ){
-    /* If z is NULL, just set *pMem to contain NULL. */
-    MemSetNull(pMem);
-    return SQLITE_OK;
-  }
-
-  tmp.z = (char *)z;
-  if( eCopy ){
-    tmp.flags = MEM_Ephem|MEM_Str;
-  }else{
-    tmp.flags = MEM_Static|MEM_Str;
-  }
-  tmp.flags |= encToFlags(enc);
-  tmp.n = n;
-  switch( enc ){
-    case 0:
-      tmp.flags |= MEM_Blob;
-      break;
-
-    case TEXT_Utf8:
-      tmp.flags |= MEM_Utf8;
-      if( n<0 ) tmp.n = strlen(z)+1;
-      tmp.flags |= ((tmp.z[tmp.n-1])?0:MEM_Term);
-      break;
-
-    case TEXT_Utf16le:
-    case TEXT_Utf16be:
-      tmp.flags |= (enc==TEXT_Utf16le?MEM_Utf16le:MEM_Utf16be);
-      if( n<0 ) tmp.n = sqlite3utf16ByteLen(z,-1)+1;
-      tmp.flags |= ((tmp.z[tmp.n-1]||tmp.z[tmp.n-2])?0:MEM_Term);
-      break;
-
-    default:
-      assert(0);
-  }
-  return sqlite3VdbeMemCopy(pMem, &tmp);
-}
-
-int sqlite3VdbeMemNulTerminate(Mem *pMem){
-  int nulTermLen;
-  int f = pMem->flags;
-
-  assert( pMem->flags&MEM_Str && !pMem->flags&MEM_Term );
-  assert( flagsToEnc(pMem->flags) );
-
-  nulTermLen = (flagsToEnc(f)==TEXT_Utf8?1:2);
-
-  if( pMem->n+nulTermLen<=NBFS ){
-    /* If the string plus the nul terminator will fit in the Mem.zShort
-    ** buffer, and it is not already stored there, copy it there.
-    */
-    if( !(f&MEM_Short) ){
-      memcpy(pMem->z, pMem->zShort, pMem->n);
-      if( f&MEM_Dyn ){
-        sqliteFree(pMem->z);
-      }
-      pMem->z = pMem->zShort;
-      pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Dyn);
-      pMem->flags |= MEM_Short;
-    }
-  }else{
-    /* Otherwise we have to malloc for memory. If the string is already
-    ** dynamic, use sqliteRealloc(). Otherwise sqliteMalloc() enough
-    ** space for the string and the nul terminator, and copy the string
-    ** data there.
-    */
-    if( f&MEM_Dyn ){
-      pMem->z = (char *)sqliteRealloc(pMem->z, pMem->n+nulTermLen);
-      if( !pMem->z ){
-        return SQLITE_NOMEM;
-      }
-    }else{
-      char *z = (char *)sqliteMalloc(pMem->n+nulTermLen);
-      memcpy(z, pMem->z, pMem->n);
-      pMem->z = z;
-      pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
-      pMem->flags |= MEM_Dyn;
-    }
-  }
-
-  /* pMem->z now points at the string data, with enough space at the end
-  ** to insert the nul nul terminator. pMem->n has not yet been updated.
-  */
-  memcpy(&pMem->z[pMem->n], "\0\0", nulTermLen);
-  pMem->n += nulTermLen;
-  pMem->flags |= MEM_Term;
-}
-
-/*
-** The following ten routines, named sqlite3_result_*(), are used to
-** return values or errors from user-defined functions and aggregate
-** operations. They are commented in the header file sqlite.h (sqlite.h.in)
-*/
-void sqlite3_result(sqlite3_context *pCtx, sqlite3_value *pValue){
-  sqlite3VdbeMemCopy(&pCtx->s, pValue);
-}
-void sqlite3_result_int32(sqlite3_context *pCtx, int iVal){
-  MemSetInt(&pCtx->s, iVal);
-}
-void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
-  MemSetInt(&pCtx->s, iVal);
-}
-void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
-  MemSetReal(&pCtx->s, rVal);
-}
-void sqlite3_result_null(sqlite3_context *pCtx){
-  MemSetNull(&pCtx->s);
-}
-void sqlite3_result_text(
-  sqlite3_context *pCtx, 
-  const char *z, 
-  int n,
-  int eCopy
-){
-  MemSetStr(&pCtx->s, z, n, TEXT_Utf8, eCopy);
-}
-void sqlite3_result_text16(
-  sqlite3_context *pCtx, 
-  const void *z, 
-  int n, 
-  int eCopy
-){
-  MemSetStr(&pCtx->s, z, n, TEXT_Utf16, eCopy);
-}
-void sqlite3_result_blob(
-  sqlite3_context *pCtx, 
-  const void *z, 
-  int n, 
-  int eCopy
-){
-  assert( n>0 );
-  MemSetStr(&pCtx->s, z, n, 0, eCopy);
-}
-void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
-  pCtx->isError = 1;
-  MemSetStr(&pCtx->s, z, n, TEXT_Utf8, 1);
-}
-void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
-  pCtx->isError = 1;
-  MemSetStr(&pCtx->s, z, n, TEXT_Utf16, 1);
-}
index 309f21960d879b9368875a081cc20b028178979c..e801a1828a11e9963ef5bc14d6c09571bac9aa4d 100644 (file)
 #include <ctype.h>
 #include "vdbeInt.h"
 
-/*
-** Given a Mem.flags value, return TEXT_Utf8, TEXT_Utf16le, or TEXT_Utf16be
-** as appropriate.
-*/
-#define flagsToEnc(F) \
-    (((F)&MEM_Utf8)?TEXT_Utf8: \
-       ((F)&MEM_Utf16be)?TEXT_Utf16be:TEXT_Utf16le)
-
 /*
 ** If pMem is a string object, this routine sets the encoding of the string
 ** (to one of UTF-8 or UTF16) and whether or not the string is
 ** nul-terminated. If pMem is not a string object, then this routine is
 ** a no-op.
 **
-** The second argument, "flags" consists of one of MEM_Utf8, MEM_Utf16le
-** or MEM_Utf16be, possible ORed with MEM_Term. If necessary this function 
-** manipulates the value stored by pMem so that it matches the flags passed
-** in "flags".
+** The second argument, "desiredEnc" is one of TEXT_Utf8, TEXT_Utf16le
+** or TEXT_Utf16be.  This routine changes the encoding of pMem to match
+** desiredEnc.
 **
 ** SQLITE_OK is returned if the conversion is successful (or not required).
 ** SQLITE_NOMEM may be returned if a malloc() fails during conversion
 ** between formats.
 */
-int sqlite3VdbeSetEncoding(Mem *pMem, int flags){
-  u8 enc1;    /* Current string encoding (TEXT_Utf* value) */
-  u8 enc2;    /* Required string encoding (TEXT_Utf* value) */
+int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
+  u8 oldEnd;    /* 
 
-  /* If this is not a string, do nothing. */
-  if( !(pMem->flags&MEM_Str) ){
+  /* If this is not a string, or if it is a string but the encoding is
+  ** already correct, do nothing. */
+  if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
     return SQLITE_OK;
   }
 
-  enc1 = flagsToEnc(pMem->flags);
-  enc2 = flagsToEnc(flags);
-
-  if( enc1!=enc2 ){
-    if( enc1==TEXT_Utf8 || enc2==TEXT_Utf8 ){
-      /* If the current encoding does not match the desired encoding, then
-      ** we will need to do some translation between encodings.
-      */
-      char *z;
-      int n;
-      int rc = sqlite3utfTranslate(pMem->z,pMem->n,enc1,(void **)&z,&n,enc2);
-      if( rc!=SQLITE_OK ){
-        return rc;
-      }
+  if( pMem->enc==TEXT_Utf8 || desiredEnd==TEXT_Utf8 ){
+    /* If the current encoding does not match the desired encoding, then
+    ** we will need to do some translation between encodings.
+    */
+    char *z;
+    int n;
+    int rc = sqlite3utfTranslate(pMem->z, pMem->n, pMem->enc,
+                                 (void **)&z, &n, desiredEnd);
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
   
-      /* Result of sqlite3utfTranslate is currently always dynamically
-      ** allocated and nul terminated. This might be altered as a performance
-      ** enhancement later.
-      */
-      pMem->z = z;
-      pMem->n = n;
-      pMem->flags = (MEM_Str | MEM_Dyn | MEM_Term | flags);
-    }else{
-      /* Must be translating between UTF-16le and UTF-16be. */
-      int i;
-      if( pMem->flags&MEM_Static ){
-        Dynamicify(pMem, enc1);
-      }
-      for(i=0; i<pMem->n; i+=2){
-        char c = pMem->z[i];
-        pMem->z[i] = pMem->z[i+1];
-        pMem->z[i+1] = c;
-      }
-      SetEncodingFlags(pMem, enc2);
+    /* Result of sqlite3utfTranslate is currently always dynamically
+    ** allocated and nul terminated. This might be altered as a performance
+    ** enhancement later.
+    */
+    pMem->z = z;
+    pMem->n = n;
+    pMem->flags &= ~(MEM_Ephem | MEM_Short | MEM_Static);
+    pMem->flags |= MEM_Str | MEM_Dyn | MEM_Term;
+  }else{
+    /* Must be translating between UTF-16le and UTF-16be. */
+    int i;
+    u8 *pFrom, *pTo;
+    sqlite3VdbeMemMakeWritable(pMem);
+    for(i=0, pFrom=pMem->z, pTo=&pMem->z[1]; i<pMem->n; i+=2, pFrom++, pTo++){
+      u8 temp = *pFrom;
+      *pFrom = *pTo;
+      *pTo = temp;
     }
   }
+  pMem->enc = desiredEnc;
+  return SQLITE_OK;
+}
 
-  if( (flags&MEM_Term) && !(pMem->flags&MEM_Term) ){
-    /* If we did not do any translation, but currently the string is
-    ** not nul terminated (and is required to be), then we add the
-    ** nul terminator now. We never have to do this if we translated
-    ** the encoding of the string, as the translation functions return
-    ** nul terminated values.
-    */
-    int f = pMem->flags;
-    int nulTermLen = 2;     /* The number of 0x00 bytes to append */
-    if( enc2==MEM_Utf8 ){
-      nulTermLen = 1;
+/*
+** Make the given Mem object MEM_Dyn.
+**
+** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
+*/
+int sqlite3VdbeMemMakeDynamicify(Mem *pMem){
+  int n;
+  u8 *z;
+  if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){
+    return SQLITE_OK;
+  }
+  assert( (pMem->flags & MEM_Dyn)==0 );
+  assert( pMem->flags & (MEM_Str|MEM_Blob) );
+  z = sqliteMallocRaw( n+2 )
+  if( z==0 ){
+    return SQLITE_NOMEM;
+  }
+  pMem->flags |= MEM_Dyn|MEM_Term;
+  memcpy(z, pMem->z, n );
+  z[n] = 0;
+  z[n+1] = 0;
+  pMem->z = z;
+  pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short);
+}
+
+/*
+** Make the given Mem object either MEM_Short or MEM_Dyn so that bytes
+** of the Mem.z[] array can be modified.
+**
+** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
+*/
+int sqlite3VdbeMemMakeWritable(Mem *pMem){
+  int n;
+  u8 *z;
+  if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){
+    return SQLITE_OK;
+  }
+  assert( (pMem->flags & MEM_Dyn)==0 );
+  assert( pMem->flags & (MEM_Str|MEM_Blob) );
+  if( (n = pMem->n)+2<sizeof(pMem->zShort) ){
+    z = pMem->zShort;
+    pMem->flags |= MEM_Short|MEM_Term;
+  }else{
+    z = sqliteMallocRaw( n+2 )
+    if( z==0 ){
+      return SQLITE_NOMEM;
     }
+    pMem->flags |= MEM_Dyn|MEM_Term;
+  }
+  memcpy(z, pMem->z, n );
+  z[n] = 0;
+  z[n+1] = 0;
+  pMem->z = z;
+  pMem->flags &= ~(MEM_Ephem|MEM_Static);
+}
 
-    if( pMem->n+nulTermLen<=NBFS ){
-      /* If the string plus the nul terminator will fit in the Mem.zShort
-      ** buffer, and it is not already stored there, copy it there.
-      */
-      if( !(f&MEM_Short) ){
-        memcpy(pMem->z, pMem->zShort, pMem->n);
-        if( f&MEM_Dyn ){
-          sqliteFree(pMem->z);
-        }
-        pMem->z = pMem->zShort;
-        pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Dyn);
-        pMem->flags |= MEM_Short;
-      }
+/*
+** Make sure the given Mem is \u0000 terminated.
+*/
+int sqlite3VdbeMemNulTerminate(Mem *pMem){
+  if( (pMem->flags & MEM_Term)!=0 || pMem->flags & (MEM_Str|MEM_Blob))==0 ){
+    return SQLITE_OK;   /* Nothing to do */
+  }
+  /* Only static or ephemeral strings can be unterminated */
+  assert( (pMem->flags & (MEM_Static|MEM_Ephem))!=0 );
+  sqlite3VdbeMemMakeWriteable(pMem);
+}
+
+/*
+** Add MEM_Str to the set of representations for the given Mem.
+** A NULL is converted into an empty string.  Numbers 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.
+** But MEM_Null is.
+*/
+int sqlite3VdbeMemStringify(Mem *pMem, int enc){
+  int rc = SQLITE_OK;
+  int fg = pMem->flags;
+
+  assert( !(fg&(MEM_Str|MEM_Blob)) );
+  assert( fg&(MEM_Int|MEM_Real|MEM_Null) );
+
+  if( fg & MEM_Null ){      
+    /* A NULL value is converted to a zero length string */
+    u8 *z = pMem->zShort;
+    z[0] = 0;
+    z[1] = 0;
+    pMem->flags = MEM_Str | MEM_Short | MEM_Term;
+    pMem->z = z;
+    pMem->n = 0;
+    pMem->enc = enc;
+  }else{
+    /* 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.
+    ** 
+    ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
+    */
+    u8 *z = pMem->zShort;
+    if( fg & MEM_Real ){
+      sqlite3_snprintf(NBFS, z, "%.15g", pMem->r);
     }else{
-      /* Otherwise we have to malloc for memory. If the string is already
-      ** dynamic, use sqliteRealloc(). Otherwise sqliteMalloc() enough
-      ** space for the string and the nul terminator, and copy the string
-      ** data there.
-      */
-      if( f&MEM_Dyn ){
-        pMem->z = (char *)sqliteRealloc(pMem->z, pMem->n+nulTermLen);
-        if( !pMem->z ){
-          return SQLITE_NOMEM;
-        }
-      }else{
-        char *z = (char *)sqliteMallocRaw(pMem->n+nulTermLen);
-        memcpy(z, pMem->z, pMem->n);
-        pMem->z = z;
-        pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
-        pMem->flags |= MEM_Dyn;
-      }
+      assert( fg & MEM_Int );
+      sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
     }
+    pMem->n = strlen(z);
+    pMem->z = n;
+    pMem->enc = TEXT_Utf8;
+    pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
+    sqlite3VdbeMemChangeEncoding(pMem, enc);
+  }
+  return rc;
+}
 
-    /* pMem->z now points at the string data, with enough space at the end
-    ** to insert the nul nul terminator. pMem->n has not yet been updated.
-    */
-    memcpy(&pMem->z[pMem->n], "\0\0", nulTermLen);
-    pMem->n += nulTermLen;
-    pMem->flags |= MEM_Term;
+/*
+** Convert the Mem to have representation MEM_Int only.  All
+** prior representations are invalidated.  NULL is converted into 0.
+*/
+int sqlite3VdbeMemIntegerify(Mem *pMem){
+  if( pMem->flags & MEM_Int ){
+    /* Do nothing */
+  }else if( pMem->flags & MEM_Real ){
+    pMem->i = (i64)pMem->r;
+  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
+    if( sqlite3VdbeChangeEncoding(pMem, TEXT_Utf8)
+       || sqlite3VdbeNulTerminate(pMem) ){
+      return SQLITE_NOMEM;
+    }
+    assert( pMem->z );
+    sqlite3atoi64(pMem->z, &pMem->i);
+  }else{
+    pMem->i = 0;
   }
-  return SQLITE_OK;
+  Release(pMem);
+  pMem->flags = MEM_Int;
+  pMem->type = SQLITE3_INTEGER;
 }
 
+/*
+** Add MEM_Real to the set of representations for pMem.  Prior
+** prior representations other than MEM_Null retained.  NULL is
+** converted into 0.0.
+*/
+int sqlite3VdbeMemRealify(Mem *pMem){
+  if( pMem->flags & MEM_Int ){
+    pMem->r = pMem->r;
+    pMem->flags |= MEM_Real;
+  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
+    if( sqlite3VdbeChangeEncoding(pMem, TEXT_Utf8)
+       || sqlite3VdbeNulTerminate(pMem) ){
+      return SQLITE_NOMEM;
+    }
+    assert( pMem->z );
+    pMem->r = sqlite3AtoF(pMem->z, 0);
+    Release(pMem);
+    pMem->flags = MEM_Real;
+    pMem->type = SQLITE3_INTEGER;
+  }else{
+    pMem->r = 0.0;
+    pMem->flags = MEM_Real;
+    pMem->type = SQLITE3_INTEGER;
+  }
+}
+
+/*
+** Release any memory held by the Mem
+*/
 static void releaseMem(Mem *p){
   if( p->flags & MEM_Dyn ){
     sqliteFree(p);
@@ -157,26 +259,29 @@ static void releaseMem(Mem *p){
 void sqlite3VdbeMemSetNull(Mem *pMem){
   releaseMem(pMem);
   pMem->flags = MEM_Null;
+  pMem->type = SQLITE3_NULL;
 }
 
 /*
 ** Delete any previous value and set the value stored in *pMem to val,
 ** manifest type INTEGER.
 */
-void sqlite3VdbeMemSetInt(Mem *pMem, i64 val){
+void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
   releaseMem(pMem);
   pMem->i = val;
   pMem->flags = MEM_Int;
+  pMem->type = SQLITE3_INTEGER;
 }
 
 /*
 ** Delete any previous value and set the value stored in *pMem to val,
 ** manifest type REAL.
 */
-void sqlite3VdbeMemSetReal(Mem *pMem, double val){
+void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
   releaseMem(pMem);
   pMem->r = val;
   pMem->flags = MEM_Real;
+  pMem->type = SQLITE3_FLOAT;
 }
 
 /*
@@ -184,36 +289,31 @@ void sqlite3VdbeMemSetReal(Mem *pMem, double val){
 */
 int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
   releaseMem(pTo);
-  memcpy(pTo, pFrom, sizeof(*pFrom));
-  if( pTo->flags&MEM_Short ){
-    pTo->z = pTo->zShort;
-  }else if( pTo->flags&(MEM_Ephem|MEM_Dyn) ){
-    pTo->flags = pTo->flags&(~(MEM_Static|MEM_Ephem|MEM_Short|MEM_Dyn));
-    if( pTo->n>NBFS ){
-      pTo->z = sqliteMalloc(pTo->n);
-      if( !pTo->z ) return SQLITE_NOMEM;
-      pTo->flags |= MEM_Dyn;
-    }else{
-      pTo->z = pTo->zShort;
-      pTo->flags |= MEM_Short;
-    }
-    memcpy(pTo->z, pFrom->z, pTo->n);
+  memcpy(pTo, pFrom, sizeof(*pFrom)-sizeof(pFrom->zShort));
+  if( pTo->flags & (MEM_Str|MEM_Blob) ){
+    pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
+    pTo->flags |= MEM_Ephem;
+    sqlite3VdbeMemMakeWriteable(pTo);
   }
   return SQLITE_OK;
 }
 
+/*
+** Change the value of a Mem to be a string or a BLOB.
+*/
 int sqlite3VdbeMemSetStr(
   Mem *pMem,          /* Memory cell to set to string value */
   const char *z,      /* String pointer */
   int n,              /* Bytes in string, or negative */
-  u8 enc,             /* Encoding of z */
+  u8 enc,             /* Encoding of z.  0 for BLOBs */
   int eCopy           /* True if this function should make a copy of z */
 ){
   Mem tmp;
 
   releaseMem(pMem);
   if( !z ){
-    /* If z is NULL, just set *pMem to contain NULL. */
+    pMem->flags = MEM_Null;
+    pMem->type = SQLITE3_NULL;
     return SQLITE_OK;
   }
 
@@ -223,7 +323,8 @@ int sqlite3VdbeMemSetStr(
   }else{
     pMem->flags = MEM_Static|MEM_Str;
   }
-  pMem->flags |= encToFlags(enc);
+  pMem->enc = enc;
+  pMem->type = enc==0 ? SQLITE3_BLOB : SQLITE3_TEXT;
   pMem->n = n;
   switch( enc ){
     case 0:
@@ -231,22 +332,16 @@ int sqlite3VdbeMemSetStr(
       break;
 
     case TEXT_Utf8:
-      pMem->flags |= MEM_Utf8;
       if( n<0 ){
-        pMem->n = strlen(z)+1;
-        pMem->flags |= MEM_Term;
-      }else if( z[pMem->n-1]==0 ){
+        pMem->n = strlen(z);
         pMem->flags |= MEM_Term;
       }
       break;
 
     case TEXT_Utf16le:
     case TEXT_Utf16be:
-      pMem->flags |= (enc==TEXT_Utf16le?MEM_Utf16le:MEM_Utf16be);
       if( n<0 ){
-        pMem->n = sqlite3utf16ByteLen(z,-1)+1;
-        pMem->flags |= MEM_Term;
-      }else if( z[pMem->n-1]==0 && z[pMem->n-2]==0 ){
+        pMem->n = sqlite3utf16ByteLen(z,-1);
         pMem->flags |= MEM_Term;
       }
       break;
@@ -254,57 +349,9 @@ int sqlite3VdbeMemSetStr(
     default:
       assert(0);
   }
-  Deephemeralize(pMem);
-}
-
-int sqlite3VdbeMemNulTerminate(Mem *pMem){
-  int nulTermLen;
-  int f = pMem->flags;
-
-  assert( pMem->flags&MEM_Str && !pMem->flags&MEM_Term );
-  assert( flagsToEnc(pMem->flags) );
-
-  nulTermLen = (flagsToEnc(f)==TEXT_Utf8?1:2);
-
-  if( pMem->n+nulTermLen<=NBFS ){
-    /* If the string plus the nul terminator will fit in the Mem.zShort
-    ** buffer, and it is not already stored there, copy it there.
-    */
-    if( !(f&MEM_Short) ){
-      memcpy(pMem->z, pMem->zShort, pMem->n);
-      if( f&MEM_Dyn ){
-        sqliteFree(pMem->z);
-      }
-      pMem->z = pMem->zShort;
-      pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Dyn);
-      pMem->flags |= MEM_Short;
-    }
-  }else{
-    /* Otherwise we have to malloc for memory. If the string is already
-    ** dynamic, use sqliteRealloc(). Otherwise sqliteMalloc() enough
-    ** space for the string and the nul terminator, and copy the string
-    ** data there.
-    */
-    if( f&MEM_Dyn ){
-      pMem->z = (char *)sqliteRealloc(pMem->z, pMem->n+nulTermLen);
-      if( !pMem->z ){
-        return SQLITE_NOMEM;
-      }
-    }else{
-      char *z = (char *)sqliteMalloc(pMem->n+nulTermLen);
-      memcpy(z, pMem->z, pMem->n);
-      pMem->z = z;
-      pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
-      pMem->flags |= MEM_Dyn;
-    }
+  if( eCopy ){
+    sqlite3VdbeMemMakeWriteable(pMem);
   }
-
-  /* pMem->z now points at the string data, with enough space at the end
-  ** to insert the nul nul terminator. pMem->n has not yet been updated.
-  */
-  memcpy(&pMem->z[pMem->n], "\0\0", nulTermLen);
-  pMem->n += nulTermLen;
-  pMem->flags |= MEM_Term;
 }
 
 /*
index 675905a8848542cc6fca20f02433ece1a8909700..c18e75b489e3805b9930f19a6ad5f3bb60239369 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script testing the sqlite_bind API.
 #
-# $Id: bind.test,v 1.9 2004/05/26 10:11:07 danielk1977 Exp $
+# $Id: bind.test,v 1.10 2004/05/27 01:53:56 drh Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -28,7 +28,7 @@ proc sqlite_step {stmt N VALS COLS} {
     lappend cols [sqlite3_column_name $stmt $i]
   }
   for {set i 0} {$i < [sqlite3_data_count $stmt]} {incr i} {
-    lappend vals [sqlite3_column_data $stmt $i]
+    lappend vals [sqlite3_column_text $stmt $i]
   }
 
   return $rc
index 277485ae349688a698876f74f5bf9d46592660f1..183f91a571938536f44f787569bc8c6e1c95ffb0 100644 (file)
@@ -13,7 +13,7 @@
 # various suported unicode encodings (UTF-8, UTF-16, UTF-16le and
 # UTF-16be).
 #
-# $Id: enc2.test,v 1.2 2004/05/26 10:11:07 danielk1977 Exp $
+# $Id: enc2.test,v 1.3 2004/05/27 01:53:56 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -91,12 +91,12 @@ do_test $t.6 {
 do_test $t.7 {
   set STMT [sqlite3_prepare $DB "SELECT a FROM t1 WHERE c>3;" -1 TAIL]
   sqlite3_step $STMT
-  sqlite3_column_data $STMT 0
+  sqlite3_column_text $STMT 0
 } {four}
 
 do_test $t.8 {
   sqlite3_step $STMT
-  utf8 [sqlite3_column_data16 $STMT 0]
+  utf8 [sqlite3_column_text16 $STMT 0]
 } {five}
 
 do_test $t.9 {
@@ -123,7 +123,3 @@ foreach enc $encodings {
 }
 
 finish_test
-
-
-
-