]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Use the new API for returning values and errors from user functions. (CVS 1453)
authordanielk1977 <danielk1977@noemail.net>
Tue, 25 May 2004 11:47:24 +0000 (11:47 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Tue, 25 May 2004 11:47:24 +0000 (11:47 +0000)
FossilOrigin-Name: 4eccae03b4a7f37804fea30416579787c3584bb2

manifest
manifest.uuid
src/date.c
src/func.c
src/md5.c
src/sqlite.h.in
src/tclsqlite.c
src/test1.c
src/vdbe.c
src/vdbeInt.h
src/vdbeaux.c

index b0633689683caf85a035d7c9a1eae822470df63a..c898089ade46dd4f8426ddcb56a94021229be7aa 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\smanifest\stype\saware\sversions\sof\sthe\smin()\sand\smax()\saggregates.\s(CVS\s1452)
-D 2004-05-25T01:13:21
+C Use\sthe\snew\sAPI\sfor\sreturning\svalues\sand\serrors\sfrom\suser\sfunctions.\s(CVS\s1453)
+D 2004-05-25T11:47:25
 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -28,16 +28,16 @@ F src/btree.c 51dfa34da5f42762b228d7360cf3273ee403bce8
 F src/btree.h b65140b5ae891f30d2a39e64b9f0343225553545
 F src/build.c 35cbeb439b49cca5eb5e8a1de010a5194f4523e8
 F src/copy.c 4d2038602fd0549d80c59bda27d96f13ea9b5e29
-F src/date.c 64fd7169c7d599ec8eaa99121d59e27ddf3d783d
+F src/date.c b754dc0e1a84b408de0ccc727c792d46ccb66a69
 F src/delete.c 2e1dda38345416a1ea1c0a6468589a7472334dac
 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
 F src/expr.c 5b283e68bd6df365b7c2ad10bd04cc54c2b4b07c
-F src/func.c 7eb4356a9e3155d6783d84fc5d6b324031877572
+F src/func.c c811d2b77f1f1d88db759cbd60b382463f5a3ae3
 F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
 F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
 F src/insert.c e510d62d23b4de4d901e7ccbbe7833b7fb3b9570
 F src/main.c 8279e1160810410bb9ad6608f87b0140db5b1ce0
-F src/md5.c 84c69162ad4c9b8399b522a259c09e256edaf88a
+F src/md5.c 8344ab774bed1bcf2f2fd4e130cc48536f37c414
 F src/os.h ab42f4a7c4c716f26b988e759b6e12085a3bfc67
 F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f
 F src/os_mac.c b823874690615ace0dd520d3ad1fe8bfd864b7e0
@@ -54,11 +54,11 @@ F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 F src/select.c 7d77a8bed7eeac23216d42fc1be006fb4352fcdc
 F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f
-F src/sqlite.h.in 3dfba192557c211779fdd48fd25b437b339eabcd
+F src/sqlite.h.in 5c9a7d2a4c438da8389382a4ecf145cad73a9238
 F src/sqliteInt.h 3ba18f1bbe85c69db1b4882ba899681b0bbac2ae
 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
-F src/tclsqlite.c c8b511645f98051f41b5e0d6c3a99feeed9aeeec
-F src/test1.c 045cdd926a8157cd24c6112c2743236063f1bf3e
+F src/tclsqlite.c 0c0600409dfc297ef026ca9c8dbdf8754e54d0c4
+F src/test1.c ae2886e9c130f0dcd49f78bd78ffa37c2cb2e7d0
 F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
 F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968
 F src/test4.c b9947c319a5c023c10c1e953e6610abd571c2283
@@ -69,10 +69,10 @@ F src/update.c 1a5e9182596f3ea8c7a141e308a3d2a7e5689fee
 F src/utf.c 1d38da85bffb928fb0d9f301e7db913a6df486ce
 F src/util.c 4c0adcbc9ce6678dd046931253e45d623c6d279f
 F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad
-F src/vdbe.c 11bb4758ae692888ee2a2566be9e0119b489dff3
+F src/vdbe.c bf205ee831161cffc924c71307e24eb61b237230
 F src/vdbe.h 391d5642a83af686f35c228fcd36cb4456d68f44
-F src/vdbeInt.h 4dfeaaf7ca34859553d62f391bfb6b6fe4be425e
-F src/vdbeaux.c 588e7df730b5d3f6cbe1f44203c91b7be0042ce5
+F src/vdbeInt.h a9a105b9232d7305b41ab36eadd0355079ff01c3
+F src/vdbeaux.c dc4fdfce9cad48d47328d7733df2ee975da6c0a0
 F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
@@ -202,7 +202,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 5c28ed5e9b5a3ecb3081ce0c5c9450d6ae8dc77d
-R 8308cdc960f78d11f007d3b61876bd79
+P b77c268ebebd5401c3f519a72cfb81438207368c
+R 4e71bf50ae3412040cd39e61cbbbc2a7
 U danielk1977
-Z 39c12ff09c771deaa84ed1f3b56e6995
+Z c2a413dbfbef432d165e1d1b259db6f9
index 6cd8c8478673c16bce676e59cf51b9b678bee803..5a8f300f1cbdd6cf43062ad39de0119e628cda4a 100644 (file)
@@ -1 +1 @@
-b77c268ebebd5401c3f519a72cfb81438207368c
\ No newline at end of file
+4eccae03b4a7f37804fea30416579787c3584bb2
\ No newline at end of file
index 21589bd1078232ebb757fec3e4e79088ac53406c..27a05876bfb982f2774f9f553702e653237bd92b 100644 (file)
@@ -16,7 +16,7 @@
 ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: date.c,v 1.21 2004/05/24 12:39:02 danielk1977 Exp $
+** $Id: date.c,v 1.22 2004/05/25 11:47:25 danielk1977 Exp $
 **
 ** NOTES:
 **
@@ -668,7 +668,7 @@ static void juliandayFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   DateTime x;
   if( isDate(argc, argv, &x)==0 ){
     computeJD(&x);
-    sqlite3_set_result_double(context, x.rJD);
+    sqlite3_result_double(context, x.rJD);
   }
 }
 
@@ -684,7 +684,7 @@ static void datetimeFunc(sqlite_func *context, int argc, sqlite3_value **argv){
     computeYMD_HMS(&x);
     sprintf(zBuf, "%04d-%02d-%02d %02d:%02d:%02d",x.Y, x.M, x.D, x.h, x.m,
            (int)(x.s));
-    sqlite3_set_result_string(context, zBuf, -1);
+    sqlite3_result_text(context, zBuf, -1, 1);
   }
 }
 
@@ -699,7 +699,7 @@ static void timeFunc(sqlite_func *context, int argc, sqlite3_value **argv){
     char zBuf[100];
     computeHMS(&x);
     sprintf(zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
-    sqlite3_set_result_string(context, zBuf, -1);
+    sqlite3_result_text(context, zBuf, -1, 1);
   }
 }
 
@@ -714,7 +714,7 @@ static void dateFunc(sqlite_func *context, int argc, sqlite3_value **argv){
     char zBuf[100];
     computeYMD(&x);
     sprintf(zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
-    sqlite3_set_result_string(context, zBuf, -1);
+    sqlite3_result_text(context, zBuf, -1, 1);
   }
 }
 
@@ -834,7 +834,7 @@ static void strftimeFunc(sqlite_func *context, int argc, sqlite3_value **argv){
     }
   }
   z[j] = 0;
-  sqlite3_set_result_string(context, z, -1);
+  sqlite3_result_text(context, z, -1, 1);
   if( z!=zBuf ){
     sqliteFree(z);
   }
index 23386b467f4e5989f4a56907e96aa68538d4035b..cf230489eabd329ec65cb86d9a3d4d0d60c19185 100644 (file)
@@ -16,7 +16,7 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: func.c,v 1.53 2004/05/25 01:13:21 danielk1977 Exp $
+** $Id: func.c,v 1.54 2004/05/25 11:47:25 danielk1977 Exp $
 */
 #include <ctype.h>
 #include <math.h>
@@ -53,7 +53,7 @@ static void minmaxFunc(sqlite_func *context, int argc, sqlite3_value **argv){
       zBest = zArg;
     }
   }
-  sqlite3_set_result_string(context, zBest, -1);
+  sqlite3_result_text(context, zBest, -1, 1);
 }
 
 /*
@@ -69,7 +69,7 @@ static void typeofFunc(sqlite_func *context, int argc, sqlite3_value **argv){
     case SQLITE3_FLOAT: z = "real" ; break;
     case SQLITE3_BLOB: z = "blob" ; break;
   }
-  sqlite3_set_result_string(context, z, -1);
+  sqlite3_result_text(context, z, -1, 0);
 }
 
 /*
@@ -87,7 +87,7 @@ static void lengthFunc(sqlite_func *context, int argc, sqlite3_value **argv){
 #else
   len = strlen(z);
 #endif
-  sqlite3_set_result_int(context, len);
+  sqlite3_result_int32(context, len);
 }
 
 /*
@@ -99,7 +99,7 @@ static void absFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   z = sqlite3_value_data(argv[0]);
   if( z==0 ) return;
   if( z[0]=='-' && isdigit(z[1]) ) z++;
-  sqlite3_set_result_string(context, z, -1);
+  sqlite3_result_text(context, z, -1, 1);
 }
 
 /*
@@ -145,7 +145,7 @@ static void substrFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
 #endif
   if( p2<0 ) p2 = 0;
-  sqlite3_set_result_string(context, &z[p1], p2);
+  sqlite3_result_text(context, &z[p1], p2, 1);
 }
 
 /*
@@ -165,7 +165,7 @@ static void roundFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
   r = sqlite3_value_float(argv[0]);
   sprintf(zBuf,"%.*f",n,r);
-  sqlite3_set_result_string(context, zBuf, -1);
+  sqlite3_result_text(context, zBuf, -1, 1);
 }
 
 /*
@@ -174,22 +174,28 @@ static void roundFunc(sqlite_func *context, int argc, sqlite3_value **argv){
 static void upperFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   char *z;
   int i;
-  if( argc<1 ) return;
-  z = sqlite3_set_result_string(context, sqlite3_value_data(argv[0]), -1);
+  if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
+  z = sqliteMalloc(sqlite3_value_bytes(argv[0]));
   if( z==0 ) return;
+  strcpy(z, sqlite3_value_data(argv[0]));
   for(i=0; z[i]; i++){
     if( islower(z[i]) ) z[i] = toupper(z[i]);
   }
+  sqlite3_result_text(context, z, -1, 1);
+  sqliteFree(z);
 }
 static void lowerFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   char *z;
   int i;
-  if( argc<1 ) return;
-  z = sqlite3_set_result_string(context, sqlite3_value_data(argv[0]), -1);
+  if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
+  z = sqliteMalloc(sqlite3_value_bytes(argv[0]));
   if( z==0 ) return;
+  strcpy(z, sqlite3_value_data(argv[0]));
   for(i=0; z[i]; i++){
     if( isupper(z[i]) ) z[i] = tolower(z[i]);
   }
+  sqlite3_result_text(context, z, -1, 1);
+  sqliteFree(z);
 }
 
 /*
@@ -201,7 +207,7 @@ static void ifnullFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   int i;
   for(i=0; i<argc; i++){
     if( SQLITE3_NULL!=sqlite3_value_type(argv[i]) ){
-      sqlite3_set_result_string(context, sqlite3_value_data(argv[i]), -1);
+      sqlite3_result_text(context, sqlite3_value_data(argv[i]), -1, 1);
       break;
     }
   }
@@ -213,7 +219,7 @@ static void ifnullFunc(sqlite_func *context, int argc, sqlite3_value **argv){
 static void randomFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   int r;
   sqlite3Randomness(sizeof(r), &r);
-  sqlite3_set_result_int(context, r);
+  sqlite3_result_int32(context, r);
 }
 
 /*
@@ -226,7 +232,7 @@ static void last_insert_rowid(
   sqlite3_value **argv
 ){
   sqlite *db = sqlite3_user_data(context);
-  sqlite3_set_result_int(context, sqlite3_last_insert_rowid(db));
+  sqlite3_result_int32(context, sqlite3_last_insert_rowid(db));
 }
 
 /*
@@ -235,7 +241,7 @@ static void last_insert_rowid(
 */
 static void change_count(sqlite_func *context, int arg, sqlite3_value **argv){
   sqlite *db = sqlite3_user_data(context);
-  sqlite3_set_result_int(context, sqlite3_changes(db));
+  sqlite3_result_int32(context, sqlite3_changes(db));
 }
 
 /*
@@ -249,7 +255,7 @@ static void last_statement_change_count(
   sqlite3_value **argv
 ){
   sqlite *db = sqlite3_user_data(context);
-  sqlite3_set_result_int(context, sqlite3_last_statement_changes(db));
+  sqlite3_result_int32(context, sqlite3_last_statement_changes(db));
 }
 
 /*
@@ -269,7 +275,7 @@ static void likeFunc(
   const unsigned char *zA = sqlite3_value_data(argv[0]);
   const unsigned char *zB = sqlite3_value_data(argv[1]);
   if( zA && zB ){
-    sqlite3_set_result_int(context, sqlite3LikeCompare(zA, zB));
+    sqlite3_result_int32(context, sqlite3LikeCompare(zA, zB));
   }
 }
 
@@ -286,7 +292,7 @@ static void globFunc(sqlite_func *context, int arg, sqlite3_value **argv){
   const unsigned char *zA = sqlite3_value_data(argv[0]);
   const unsigned char *zB = sqlite3_value_data(argv[1]);
   if( zA && zB ){
-    sqlite3_set_result_int(context, sqlite3GlobCompare(zA, zB));
+    sqlite3_result_int32(context, sqlite3GlobCompare(zA, zB));
   }
 }
 
@@ -299,7 +305,7 @@ static void nullifFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   const unsigned char *zX = sqlite3_value_data(argv[0]);
   const unsigned char *zY = sqlite3_value_data(argv[1]);
   if( zX!=0 && sqlite3Compare(zX, zY)!=0 ){
-    sqlite3_set_result_string(context, zX, -1);
+    sqlite3_result_text(context, zX, -1, 1);
   }
 }
 
@@ -308,7 +314,7 @@ static void nullifFunc(sqlite_func *context, int argc, sqlite3_value **argv){
 ** of the SQLite library that is running.
 */
 static void versionFunc(sqlite_func *context, int argc, sqlite3_value **argv){
-  sqlite3_set_result_string(context, sqlite3_version, -1);
+  sqlite3_result_text(context, sqlite3_version, -1, 0);
 }
 
 /*
@@ -326,9 +332,9 @@ static void quoteFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   const char *zArg = sqlite3_value_data(argv[0]);
   if( argc<1 ) return;
   if( zArg==0 ){
-    sqlite3_set_result_string(context, "NULL", 4);
+    sqlite3_result_text(context, "NULL", 4, 0);
   }else if( sqlite3IsNumber(zArg, 0, TEXT_Utf8) ){
-    sqlite3_set_result_string(context, zArg, -1);
+    sqlite3_result_text(context, zArg, -1, 1);
   }else{
     int i,j,n;
     char *z;
@@ -344,7 +350,7 @@ static void quoteFunc(sqlite_func *context, int argc, sqlite3_value **argv){
     }
     z[j++] = '\'';
     z[j] = 0;
-    sqlite3_set_result_string(context, z, j);
+    sqlite3_result_text(context, z, j, 1);
     sqliteFree(z);
   }
 }
@@ -382,9 +388,9 @@ static void soundexFunc(sqlite_func *context, int argc, sqlite3_value **argv){
       zResult[j++] = '0';
     }
     zResult[j] = 0;
-    sqlite3_set_result_string(context, zResult, 4);
+    sqlite3_result_text(context, zResult, 4, 1);
   }else{
-    sqlite3_set_result_string(context, "?000", 4);
+    sqlite3_result_text(context, "?000", 4, 0);
   }
 }
 #endif
@@ -428,7 +434,7 @@ static void randStr(sqlite_func *context, int argc, sqlite3_value **argv){
     zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
   }
   zBuf[n] = 0;
-  sqlite3_set_result_string(context, zBuf, n);
+  sqlite3_result_text(context, zBuf, n, 1);
 }
 #endif
 
@@ -457,13 +463,13 @@ static void sumStep(sqlite_func *context, int argc, sqlite3_value **argv){
 static void sumFinalize(sqlite_func *context){
   SumCtx *p;
   p = sqlite3_aggregate_context(context, sizeof(*p));
-  sqlite3_set_result_double(context, p ? p->sum : 0.0);
+  sqlite3_result_double(context, p ? p->sum : 0.0);
 }
 static void avgFinalize(sqlite_func *context){
   SumCtx *p;
   p = sqlite3_aggregate_context(context, sizeof(*p));
   if( p && p->cnt>0 ){
-    sqlite3_set_result_double(context, p->sum/(double)p->cnt);
+    sqlite3_result_double(context, p->sum/(double)p->cnt);
   }
 }
 
@@ -527,7 +533,7 @@ static void countStep(sqlite_func *context, int argc, sqlite3_value **argv){
 static void countFinalize(sqlite_func *context){
   CountCtx *p;
   p = sqlite3_aggregate_context(context, sizeof(*p));
-  sqlite3_set_result_int(context, p ? p->n : 0);
+  sqlite3_result_int32(context, p ? p->n : 0);
 }
 
 /*
@@ -552,13 +558,21 @@ static void minmaxStep(sqlite_func *context, int argc, sqlite3_value **argv){
   if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
 
   if( pBest->flags ){
+    /* This step function is used for both the min() and max() aggregates,
+    ** the only difference between the two being that the sense of the
+    ** comparison is inverted. For the max() aggregate, the
+    ** sqlite3_user_data() function returns (void *)-1. For min() it
+    ** returns (void *)db, where db is the sqlite3* database pointer.
+    ** Therefore the next statement sets variable 'max' to 1 for the max()
+    ** aggregate, or 0 for min().
+    */
     max = ((sqlite3_user_data(context)==(void *)-1)?1:0);
     cmp = sqlite3MemCompare(pBest, pArg, 0);
     if( (max && cmp<0) || (!max && cmp>0) ){
-      sqlite3MemCopy(pBest, pArg);
+      sqlite3VdbeMemCopy(pBest, pArg);
     }
   }else{
-    sqlite3MemCopy(pBest, pArg);
+    sqlite3VdbeMemCopy(pBest, pArg);
   }
 }
 static void minMaxFinalize(sqlite_func *context){
@@ -568,15 +582,14 @@ static void minMaxFinalize(sqlite_func *context){
   if( pRes->flags ){
     switch( sqlite3_value_type(pRes) ){
       case SQLITE3_INTEGER: 
-        sqlite3_set_result_int(context, sqlite3_value_int(pRes));
+        sqlite3_result_int32(context, sqlite3_value_int(pRes));
         break;
       case SQLITE3_FLOAT: 
-        sqlite3_set_result_double(context, sqlite3_value_float(pRes));
+        sqlite3_result_double(context, sqlite3_value_float(pRes));
       case SQLITE3_TEXT: 
       case SQLITE3_BLOB: 
-        sqlite3_set_result_string(context,
-            sqlite3_value_data(pRes),
-            sqlite3_value_bytes(pRes));
+        sqlite3_result_text(context,
+            sqlite3_value_data(pRes), sqlite3_value_bytes(pRes), 1);
         break;
       case SQLITE3_NULL: 
       default:
index 0d0f3f479459136ecd4cac9b4a8ab9be8efd1307..77f3d49945c0f13d6bed505c078bf3ef97552ac8 100644 (file)
--- a/src/md5.c
+++ b/src/md5.c
@@ -379,7 +379,7 @@ static void md5finalize(sqlite_func *context){
   p = sqlite3_aggregate_context(context, sizeof(*p));
   MD5Final(digest,p);
   DigestToBase16(digest, zBuf);
-  sqlite3_set_result_string(context, zBuf, strlen(zBuf));
+  sqlite3_result_text(context, zBuf, -1, 1);
 }
 void Md5_Register(sqlite *db){
   sqlite3_create_aggregate(db, "md5sum", -1, md5step, md5finalize, 0);
index ab696c6804dd7d775e96ed6bce13012cdeb80f85..1df7ef43b947a134879332eb20fb8bd428375690 100644 (file)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.74 2004/05/24 23:48:27 danielk1977 Exp $
+** @(#) $Id: sqlite.h.in,v 1.75 2004/05/25 11:47:26 danielk1977 Exp $
 */
 #ifndef _SQLITE_H_
 #define _SQLITE_H_
@@ -464,36 +464,6 @@ int sqlite3_function_type(
 #define SQLITE_TEXT        (-2)
 #define SQLITE_ARGS        (-3)
 
-/*
-** The user function implementations call one of the following four routines
-** in order to return their results.  The first parameter to each of these
-** routines is a copy of the first argument to xFunc() or xFinialize().
-** The second parameter to these routines is the result to be returned.
-** A NULL can be passed as the second parameter to sqlite3_set_result_string()
-** in order to return a NULL result.
-**
-** The 3rd argument to _string and _error is the number of characters to
-** take from the string.  If this argument is negative, then all characters
-** up to and including the first '\000' are used.
-**
-** The sqlite3_set_result_string() function allocates a buffer to hold the
-** result and returns a pointer to this buffer.  The calling routine
-** (that is, the implmentation of a user function) can alter the content
-** of this buffer if desired.
-*/
-char *sqlite3_set_result_string(sqlite_func*,const char*,int);
-void sqlite3_set_result_int(sqlite_func*,int);
-void sqlite3_set_result_double(sqlite_func*,double);
-void sqlite3_set_result_error(sqlite_func*,const char*,int);
-
-/*
-** The pUserData parameter to the sqlite3_create_function() and
-** sqlite3_create_aggregate() routines used to register user functions
-** is available to the implementation of the function using this
-** call.
-*/
-void *sqlite3_user_data(sqlite_func*);
-
 /*
 ** Aggregate functions use the following routine to allocate
 ** a structure for storing their state.  The first time this routine
@@ -1412,6 +1382,98 @@ long long int sqlite3_value_int(sqlite3_value*);
 */
 double sqlite3_value_float(sqlite3_value*);
 
+typedef sqlite_func sqlite3_context;
+
+void *sqlite3_get_context(sqlite3_context*, int nbyte);
+
+/*
+** The pUserData parameter to the sqlite3_create_function() and
+** sqlite3_create_aggregate() routines used to register user functions
+** is available to the implementation of the function using this
+** call.
+*/
+void *sqlite3_user_data(sqlite3_context*);
+
+/*
+** The following three functions may be called from within a user-defined
+** function callback or a user-defined aggregate finalizer callback. The
+** result of the user-defined function or aggregate is set to the value of
+** the second parameter. Any value previously set as the return value via
+** an sqlite3_result_*() call is overwritten.
+**
+** The first parameter to each of these routines must be a copy of the
+** sqlite3_context* pointer passed to the user-defined function or
+** aggregate finalizer function.
+*/
+void sqlite3_result_int32(sqlite3_context*, int);
+void sqlite3_result_int64(sqlite3_context*, long long int);
+void sqlite3_result_double(sqlite3_context*, double);
+
+/*
+** This function may be called from within a user-defined function callback
+** or a user-defined aggregate finalizer callback. The result of the
+** user-defined function or aggregate is set to NULL.  Any value previously
+** set as the return value via an sqlite3_result_*() call is overwritten.
+**
+** The parameter to this routine must be a copy of the sqlite3_context*
+** pointer passed to the user-defined function or aggregate finalizer
+** function.
+*/
+void sqlite3_result_null(sqlite3_context*);
+
+/*
+** The following two functions may be called from within a user-defined or
+** a user-defined aggregate finalizer callback to return a text value. 
+** The second parameter is a pointer to the string, encoded in UTF-8 
+** for sqlite3_result_text() and UTF-16 (machine byte order) for
+** sqlite3_result_text16(). 
+**
+** If the third parameter, n,  is positive, it is the number of bytes (not
+** characters) in the string data. A negative n value indicates that the
+** string may be read up to the nul terminator character.
+**
+** If the fourth parameter is non-zero, then a copy is made of the string.
+** Otherwise, SQLite stores a pointer to the original string data.
+**
+** The first parameter to this routine must be a copy of the
+** sqlite3_context* pointer passed to the user-defined function or
+** aggregate finalizer function.
+*/
+void sqlite3_result_text(sqlite3_context*, const char*, int n, int eCopy);
+void sqlite3_result_text16(sqlite3_context*, const void*, int n, int eCopy);
+
+/*
+** The following function may be called from within a user-defined or a
+** user-defined aggregate finalizer callback to return a blob value.  The
+** second parameter is a pointer to the blob of data. The third parameter
+** is the number of bytes of data in the blob.
+**
+** If the fourth parameter is non-zero, then a copy is made of the blob.
+** Otherwise, SQLite stores a pointer to the original blob data.
+**
+** The first parameter to this routine must be a copy of the
+** sqlite3_context* pointer passed to the user-defined function or
+** aggregate finalizer function.
+*/
+void sqlite3_result_blob(sqlite3_context*, const void*, int n, int eCopy);
+
+/*
+** These routines are used from within a user-defined or a user-defined
+** aggregate finalizer callback to return an error. The second parameter
+** is a pointer to a string describing the error, or NULL if no explanation
+** is provided.
+**
+** The string should be encoded in UTF-8 for sqlite3_result_error() and
+** UTF-16 (machine byte order) for sqlite3_result_error16().
+**
+** If not negative, the third parameter is the number of bytes (not
+** characters) in the string passed as the second argument. If the third
+** parameter is negative, then the string is read up to the first nul
+** terminator character.
+*/
+void sqlite3_result_error(sqlite3_context*, const char*, int);
+void sqlite3_result_error16(sqlite3_context*, const void*, int);
+
 #ifdef __cplusplus
 }  /* End of the 'extern "C"' block */
 #endif
index cf60288cffe2929d777243cffd38cce7f68ca62b..a2b4983bdd2bde8a5f38a4403bc657a9d11061df 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** A TCL Interface to SQLite
 **
-** $Id: tclsqlite.c,v 1.67 2004/05/24 12:39:02 danielk1977 Exp $
+** $Id: tclsqlite.c,v 1.68 2004/05/25 11:47:26 danielk1977 Exp $
 */
 #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
 
@@ -396,9 +396,9 @@ static void tclSqlFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   }
   rc = Tcl_Eval(p->interp, Tcl_DStringValue(&cmd));
   if( rc ){
-    sqlite3_set_result_error(context, Tcl_GetStringResult(p->interp), -1); 
+    sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 
   }else{
-    sqlite3_set_result_string(context, Tcl_GetStringResult(p->interp), -1);
+    sqlite3_result_text(context, Tcl_GetStringResult(p->interp), -1, 1);
   }
 }
 #ifndef SQLITE_OMIT_AUTHORIZATION
index 57016e320b1dfc5baccca9ec69af0b178eed37e8..169118713832d43e604c2cb948c8c7525828289e 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.49 2004/05/24 23:48:27 danielk1977 Exp $
+** $Id: test1.c,v 1.50 2004/05/25 11:47:26 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -311,7 +311,7 @@ static void ifnullFunc(sqlite_func *context, int argc, sqlite3_value **argv){
   int i;
   for(i=0; i<argc; i++){
     if( SQLITE3_NULL!=sqlite3_value_type(argv[i]) ){
-      sqlite3_set_result_string(context, sqlite3_value_data(argv[i]), -1);
+      sqlite3_result_text(context, sqlite3_value_data(argv[i]), -1, 1);
       break;
     }
   }
@@ -386,7 +386,7 @@ static void sqlite3ExecFunc(
   sqlite3_exec((sqlite*)sqlite3_user_data(context),
       sqlite3_value_data(argv[0]),
       execFuncCallback, &x, 0);
-  sqlite3_set_result_string(context, x.z, x.nUsed);
+  sqlite3_result_text(context, x.z, x.nUsed, 1);
   sqliteFree(x.z);
 }
 
@@ -441,7 +441,7 @@ static void countStep(sqlite_func *context, int argc, sqlite3_value **argv){
 static void countFinalize(sqlite_func *context){
   CountCtx *p;
   p = sqlite3_aggregate_context(context, sizeof(*p));
-  sqlite3_set_result_int(context, p ? p->n : 0);
+  sqlite3_result_int32(context, p ? p->n : 0);
 }
 
 /*
@@ -658,19 +658,19 @@ static void testFunc(sqlite_func *context, int argc, sqlite3_value **argv){
     const char *zArg0 = sqlite3_value_data(argv[0]);
     const char *zArg1 = sqlite3_value_data(argv[1]);
     if( zArg0==0 ){
-      sqlite3_set_result_error(context, "first argument to test function "
+      sqlite3_result_error(context, "first argument to test function "
          "may not be NULL", -1);
     }else if( sqlite3StrICmp(zArg0,"string")==0 ){
-      sqlite3_set_result_string(context, zArg1, -1);
+      sqlite3_result_text(context, zArg1, -1, 1);
     }else if( zArg1==0 ){
-      sqlite3_set_result_error(context, "2nd argument may not be NULL if the "
+      sqlite3_result_error(context, "2nd argument may not be NULL if the "
          "first argument is not \"string\"", -1);
     }else if( sqlite3StrICmp(zArg0,"int")==0 ){
-      sqlite3_set_result_int(context, atoi(zArg1));
+      sqlite3_result_int32(context, atoi(zArg1));
     }else if( sqlite3StrICmp(zArg0,"double")==0 ){
-      sqlite3_set_result_double(context, sqlite3AtoF(zArg1, 0));
+      sqlite3_result_double(context, sqlite3AtoF(zArg1, 0));
     }else{
-      sqlite3_set_result_error(context,"first argument should be one of: "
+      sqlite3_result_error(context,"first argument should be one of: "
           "string int double", -1);
     }
     argc -= 2;
index 14cb55035a8db9a769ddc139107a938dafc67108..aa4645bc89e1081ec8ed72733ae3ff8323b04d45 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.327 2004/05/24 23:48:27 danielk1977 Exp $
+** $Id: vdbe.c,v 1.328 2004/05/25 11:47:26 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -69,14 +69,109 @@ 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_Utf16le?TEXT_Utf16be:TEXT_Utf8) )
+
+/*
+** The following macros each take one parameter, a pointer to a Mem
+** structure. The value returned is non-zero if the value stored in 
+** the Mem structure is of or can be losslessly converted to the
+** type implicit in the macro name.
+** 
+** MemIsNull     # NULL values
+** MemIsInt      # Ints and reals and strings that can be converted to ints.
+** MemIsReal     # Reals, ints and strings that look like numbers
+** MemIsStr      # Strings, reals and ints.
+** MemIsBlob     # Blobs.
+**
+** These macros do not alter the contents of the Mem structure.
+*/
+#define MemIsNull(p) ((p)->flags&Mem_Null)
+#define MemIsBlob(p) ((p)->flags&Mem_Blob)
+#define MemIsStr(p) ((p)->flags&(MEM_Int|MEM_Real|MEM_Str))
+#define MemIsInt(p) ((p)->flags&MEM_Int || hardMemIsInt(p))
+#define MemIsReal(p) ((p)->flags&(MEM_Int|MEM_Real) || hardMemIsReal(p))
+static int hardMemIsInt(Mem *p){
+  assert( !(p->flags&(MEM_Int|MEM_Real)) );
+  if( p->flags&MEM_Str ){
+    int realnum = 0;
+    if( sqlite3IsNumber(p->z, &realnum, MemEnc(p)) && !realnum ){
+      return 1;
+    }
+  }
+  return 0;
+}
+static int hardMemIsReal(Mem *p){
+  assert( !(p->flags&(MEM_Int|MEM_Real)) );
+  if( p->flags&MEM_Str && sqlite3IsNumber(p->z, 0, MemEnc(p)) ){
+    return 1;
+  }
+  return 0;
+}
+
+/*
+** The following two macros each take one parameter, a pointer to a Mem
+** structure. They return the value stored in the Mem structure coerced
+** to a 64-bit integer or real, respectively.
+**
+** MemInt
+** MemReal
+**
+** These macros do not alter the contents of the Mem structure, although
+** they may cache the integer or real value cast of the value.
+*/
+#define MemInt(p) (((p)->flags&MEM_Int)?(p)->i:hardMemInt(p))
+#define MemReal(p) (((p)->flags&MEM_Real)?(p)->i:hardMemReal(p))
+static i64 hardMemInt(Mem *p){
+  assert( !(p->flags&MEM_Int) );
+  if( !MemIsInt(p) ) return 0;
+
+  if( p->flags&MEM_Real ){
+    p->i = p->r;
+  }else{
+    assert( p->flags&MEM_Str );
+    sqlite3atoi64(p->z, &(p->i), MemEnc(p));
+  }
+  p->flags |= MEM_Int;
+  return p->i;
+}
+static double hardMemReal(Mem *p){
+  assert( !(p->flags&MEM_Real) );
+  if( !MemIsReal(p) ) return 0.0;
+
+  if( p->flags&MEM_Int ){
+    p->r = p->i;
+  }else{
+    assert( p->flags&MEM_Str );
+    /* p->r = sqlite3AtoF(p->z, 0, MemEnc(p)); */
+    p->r = sqlite3AtoF(p->z, 0);
+  }
+  p->flags |= MEM_Real;
+  return p->r;
+}
+
+
 #if 0
 /*
-** NulTermify
-** Stringify
-** Integerify
-** Realify
-** SetEncoding
-** Release
+** MemStr(Mem *pMem)
+** MemBlob(Mem *pMem)
+** MemBloblen(Mem *pMem)
+**
+** MemType(Mem *pMem)
+**
+** MemSetBlob
+** MemSetStr
+**
+** MemSetEnc
+** MemSetType
+**
+** MemCopy
 */
 struct MemRecord {
   char *zData;    /* Serialized record */
@@ -2012,6 +2107,7 @@ case OP_Callback: {
   for(i=0; i<pOp->p1; i++){
     Mem *pVal = &pTos[0-i];
     SetEncodingFlags(pVal, db->enc);
+    MemNulTerminate(pVal);
   }
 
   p->resOnStack = 1;
@@ -2274,14 +2370,14 @@ case OP_Function: {
   (*ctx.pFunc->xFunc)(&ctx, n, apVal);
   if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
   popStack(&pTos, n);
+
+  /* Copy the result of the function to the top of the stack */
   pTos++;
   *pTos = ctx.s;
-  if( pTos->flags & MEM_Str ){
-    pTos->flags |= MEM_Term;
-  }
   if( pTos->flags & MEM_Short ){
     pTos->z = pTos->zShort;
   }
+  /* If the function returned an error, throw an exception */
   if( ctx.isError ){
     sqlite3SetString(&p->zErrMsg, 
        (pTos->flags & MEM_Str)!=0 ? pTos->z : "user function error", (char*)0);
@@ -2289,7 +2385,6 @@ case OP_Function: {
   }
 
   if( pTos->flags&MEM_Str ){
-    SetEncodingFlags(pTos, TEXT_Utf8);
     SetEncoding(pTos, encToFlags(db->enc)|MEM_Term);
   }
 
index 679a6c33d0fba00d5eed68e98fe9d89a43d1b5ce..0061046877f5c16b6b6e0163b87bb2ed7f933625 100644 (file)
@@ -117,8 +117,15 @@ struct Sorter {
 #define NBFS 32
 
 /*
-** A single level of the stack or a single memory cell
-** is an instance of the following structure. 
+** Internally, the vdbe manipulates nearly all SQL values as Mem
+** structures. Each Mem struct may cache multiple representations (string,
+** integer etc.) of the same value.  A value (and therefore Mem structure)
+** has the following properties:
+**
+** Each value has a manifest type. The manifest type of the value stored
+** in a Mem struct is returned by the MemType(Mem*) macro. The type is
+** one of SQLITE3_NULL, SQLITE3_INTEGER, SQLITE3_REAL, SQLITE3_TEXT or
+** SQLITE3_BLOB.
 */
 struct Mem {
   i64 i;              /* Integer value */
@@ -130,6 +137,33 @@ struct Mem {
 };
 typedef struct Mem Mem;
 
+/*
+** The following three macros are used to set the value and manifest type
+** stored by a Mem structure.
+**
+** MemSetNull - Set the value to NULL.
+** MemSetInt  - Set the value to an integer.
+** MemSetReal - Set the value to a real.
+** MemSetStr - Set the value to a string.
+*/
+#define MemSetNull(p) sqlite3VdbeMemSetNull(p)
+#define MemSetInt(p,v) sqlite3VdbeMemSetInt(p,v)
+#define MemSetReal(p,v) sqlite3VdbeMemSetReal(p,v)
+#define MemSetStr(p,z,n,enc,eCopy) sqlite3VdbeMemSetStr(p,z,n,enc,eCopy)
+
+/*
+** This macro is used to ensure a string stored in a Mem struct is NULL
+** terminated. When used on an object that is not a string or is a nul
+** terminated string this is a no-op. When used on a non-nul-terminated
+** string a nul terminator character is appended.
+**
+** Non-zero is returned if a malloc() fails.
+*/
+#define MemNulTerminate(p) ( \
+  ((p)->flags&MEM_Str) && \
+  !((p)->flags&MEM_Term) && \
+  sqlite3VdbeMemNulTerminate(p) )
+
 /*
 ** Allowed values for Mem.flags.
 **
@@ -147,7 +181,6 @@ typedef struct Mem Mem;
 #define MEM_Int       0x0004   /* Value is an integer */
 #define MEM_Real      0x0008   /* Value is a real number */
 #define MEM_Blob      0x0010   /* Value is a BLOB */
-#define MEM_Struct    0x0020   /* Value is some kind of struct */
 
 #define MEM_Term      0x0200   /* String has a nul terminator character */
 
@@ -361,9 +394,10 @@ int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
 int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*);
 int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
 int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
-int sqlite3MemCopy(Mem*, const Mem*);
 int sqlite3VdbeKeyCompare(void*,int,const void*,int, const void*);
 int sqlite3VdbeRowCompare(void*,int,const void*,int, const void*);
 int sqlite3VdbeExec(Vdbe*);
 int sqlite3VdbeList(Vdbe*);
 int sqlite3VdbeSetEncoding(Mem *, u8);
+int sqlite3VdbeMemCopy(Mem*, const Mem*);
+int sqlite3VdbeMemNulTerminate(Mem *);
index 8d02b917138ae4afd87eabe88d009b3e1b2cb0d7..6ff1d6791ee23064394ba4b4f7e87edf598eba47 100644 (file)
@@ -424,83 +424,11 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
   return &p->aOp[addr];
 }
 
-/*
-** The following group or routines are employed by installable functions
-** to return their results.
-**
-** The sqlite3_set_result_string() routine can be used to return a string
-** value or to return a NULL.  To return a NULL, pass in NULL for zResult.
-** A copy is made of the string before this routine returns so it is safe
-** to pass in an ephemeral string.
-**
-** sqlite3_set_result_error() works like sqlite3_set_result_string() except
-** that it signals a fatal error.  The string argument, if any, is the
-** error message.  If the argument is NULL a generic substitute error message
-** is used.
-**
-** The sqlite3_set_result_int() and sqlite3_set_result_double() set the return
-** value of the user function to an integer or a double.
-**
-** These routines are defined here in vdbe.c because they depend on knowing
-** the internals of the sqlite_func structure which is only defined in 
-** this source file.
-*/
-char *sqlite3_set_result_string(sqlite_func *p, const char *zResult, int n){
-  assert( !p->isStep );
-  if( p->s.flags & MEM_Dyn ){
-    sqliteFree(p->s.z);
-  }
-  if( zResult==0 ){
-    p->s.flags = MEM_Null;
-    n = 0;
-    p->s.z = 0;
-    p->s.n = 0;
-  }else{
-    if( n<0 ) n = strlen(zResult);
-    if( n<NBFS-1 ){
-      memcpy(p->s.zShort, zResult, n);
-      p->s.zShort[n] = 0;
-      p->s.flags = MEM_Utf8 | MEM_Str | MEM_Short;
-      p->s.z = p->s.zShort;
-    }else{
-      p->s.z = sqliteMallocRaw( n+1 );
-      if( p->s.z ){
-        memcpy(p->s.z, zResult, n);
-        p->s.z[n] = 0;
-      }
-      p->s.flags = MEM_Utf8 | MEM_Str | MEM_Dyn;
-    }
-    p->s.n = n+1;
-  }
-  return p->s.z;
-}
-void sqlite3_set_result_int(sqlite_func *p, int iResult){
-  assert( !p->isStep );
-  if( p->s.flags & MEM_Dyn ){
-    sqliteFree(p->s.z);
-  }
-  p->s.i = iResult;
-  p->s.flags = MEM_Int;
-}
-void sqlite3_set_result_double(sqlite_func *p, double rResult){
-  assert( !p->isStep );
-  if( p->s.flags & MEM_Dyn ){
-    sqliteFree(p->s.z);
-  }
-  p->s.r = rResult;
-  p->s.flags = MEM_Real;
-}
-void sqlite3_set_result_error(sqlite_func *p, const char *zMsg, int n){
-  assert( !p->isStep );
-  sqlite3_set_result_string(p, zMsg, n);
-  p->isError = 1;
-}
-
 /*
 ** Extract the user data from a sqlite_func structure and return a
 ** pointer to it.
 */
-void *sqlite3_user_data(sqlite_func *p){
+void *sqlite3_user_data(sqlite3_context *p){
   assert( p && p->pFunc );
   return p->pFunc->pUserData;
 }
@@ -1461,33 +1389,6 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
   return rc;
 }
 
-/*
-** Copy the contents of memory cell pFrom into pTo.
-*/
-int sqlite3MemCopy(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;
-}
-
 /*
 ** The following is the comparison function for (non-integer)
 ** keys in the btrees.  This function returns negative, zero, or
@@ -1753,3 +1654,230 @@ 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 nine 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_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);
+}
+