1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Refactoring of the vdbe Mem functions and the APIs that deal with them.

The code will not compile in its current state. (CVS 1465)

FossilOrigin-Name: bba6684d502ba1ecd9614d2470ec94296e3c07c2
This commit is contained in:
drh
2004-05-26 23:25:30 +00:00
parent f9b596ebc0
commit 4f26d6c429
15 changed files with 1157 additions and 1552 deletions

View File

@@ -1,5 +1,5 @@
C Remove\sdataType\sand\sincludeTypes\sflags\sfrom\sfunction\sdefinitions.\s\sAdded\snew\nP3_FUNCDEF\stype\sfor\sP3\sarguments\son\sopcodes.\s\sFixes\sto\sseveral\suser\sfunctions.\n28\stests\sfail\snow.\s(CVS\s1464) C Refactoring\sof\sthe\svdbe\sMem\sfunctions\sand\sthe\sAPIs\sthat\sdeal\swith\sthem.\nThe\scode\swill\snot\scompile\sin\sits\scurrent\sstate.\s(CVS\s1465)
D 2004-05-26T16:54:42 D 2004-05-26T23:25:31
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -28,17 +28,17 @@ F src/btree.c 6db76fbf63efd6008c5e6cb038ea40f94abffcf7
F src/btree.h b65140b5ae891f30d2a39e64b9f0343225553545 F src/btree.h b65140b5ae891f30d2a39e64b9f0343225553545
F src/build.c 35cbeb439b49cca5eb5e8a1de010a5194f4523e8 F src/build.c 35cbeb439b49cca5eb5e8a1de010a5194f4523e8
F src/copy.c 6eb7cc08ae6dc60bf83ecadf4508a0bef909dbd2 F src/copy.c 6eb7cc08ae6dc60bf83ecadf4508a0bef909dbd2
F src/date.c 37bb5784da38457d0762281e0176b27e5aa00cf5 F src/date.c 0eb922af5c5f5e2455f8dc2f98023ed3e04a857e
F src/delete.c 66c5ab98cbad7e6b315fc997bfe6c8080784a701 F src/delete.c 66c5ab98cbad7e6b315fc997bfe6c8080784a701
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
F src/expr.c 90573f18f946c94848d5ca1c925a141ef5dfe111 F src/expr.c 90573f18f946c94848d5ca1c925a141ef5dfe111
F src/func.c 6274bceb41a032ff60297a992f54861e9d63cb20 F src/func.c a25ec101ac83e62abb249d4d3e5204c60a772224
F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
F src/insert.c dd117e8b3f50e943e6cf5fbcf4bbdc0b907b0b4c F src/insert.c dd117e8b3f50e943e6cf5fbcf4bbdc0b907b0b4c
F src/legacy.c a856d2d5317ed2ac93c2c6cbba7d4faa564a5b20 F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
F src/main.c 488ec788a06019521e53ffd25c4af97943937fb5 F src/main.c 488ec788a06019521e53ffd25c4af97943937fb5
F src/md5.c 833671b541a76fc0e62404433c9176706eeacdf0 F src/md5.c d2c738fedfb27f73cefcf2b0ac1f9f21894b073e
F src/os.h ab42f4a7c4c716f26b988e759b6e12085a3bfc67 F src/os.h ab42f4a7c4c716f26b988e759b6e12085a3bfc67
F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f
F src/os_mac.c b823874690615ace0dd520d3ad1fe8bfd864b7e0 F src/os_mac.c b823874690615ace0dd520d3ad1fe8bfd864b7e0
@@ -55,14 +55,14 @@ F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c e90e2a147273cdcdb1ee9e14574ab28f04382e63 F src/select.c e90e2a147273cdcdb1ee9e14574ab28f04382e63
F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f
F src/sqlite.h.in 91a42246b390974361fdf8daf273d6c3bbf95e85 F src/sqlite.h.in 68e165dc4dc2d477c95c76b9ede13eed5fbaabf4
F src/sqliteInt.h 6b0d8d856c4af325eb5a00d1c32d89aacf432875 F src/sqliteInt.h 6b0d8d856c4af325eb5a00d1c32d89aacf432875
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
F src/tclsqlite.c b9386659cec1eac402ac7a2371deefe70709bf6a F src/tclsqlite.c 86daf7bf6ba715bf0f0c7a47beb1d947a15cb868
F src/test1.c f8dacbbdfa206ed975c02842c52dee0c97952817 F src/test1.c f9d1e36b87b5a2253dabd4c563e110e8d8273dbf
F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872 F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968 F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968
F src/test4.c 014478492bddb3f9b4a3151b05f9ac708fe279fb F src/test4.c 34848a9fd31aa65857b20a8bfc03aff77d8c3426
F src/test5.c 9a1f15133f6955f067c5246e564723b5f23ff221 F src/test5.c 9a1f15133f6955f067c5246e564723b5f23ff221
F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847 F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f
@@ -70,10 +70,12 @@ F src/update.c 96461bcf4e946697e83c09c77c7e61b545a2f66e
F src/utf.c 1d38da85bffb928fb0d9f301e7db913a6df486ce F src/utf.c 1d38da85bffb928fb0d9f301e7db913a6df486ce
F src/util.c 4c0adcbc9ce6678dd046931253e45d623c6d279f F src/util.c 4c0adcbc9ce6678dd046931253e45d623c6d279f
F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad
F src/vdbe.c a4b2f800137c652433b786537f1750ee769b2014 F src/vdbe.c 4419d3b7e4d56b0c1d973ebf4de40ee5045e612e
F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb
F src/vdbeInt.h 1064ce1723c9c739772af2903e7e06ad2b214be1 F src/vdbeInt.h d7eda2403e11de5e0c581f91bd202cc952190a97
F src/vdbeaux.c 951985ea55c6bac6dcd0041ee652a4eec2a65b06 F src/vdbeapi.c 36d4c78bc765dc89cac07ff975b26256e0ac90fc
F src/vdbeaux.c 677317be4021eadce96365b16d9deeda9e565bef
F src/vdbemem.c c92c41c80c333b3cd405a08ebfd014d02a9f7b8c
F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
@@ -203,7 +205,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P ce8b15203413f38a8b7127eb08ae5db1c1eb164a P 36e031625995b2f7baf7654d771ca8fb764a0085
R d2e1633ebc6abb34ef4a297a6d817967 R f8551815839ed9151ff9855a8a833baa
U drh U drh
Z 933339c84dc9b3a3ef071d1cac60a7a8 Z af6c613d004b8ea284a0c6f10b3031e5

View File

@@ -1 +1 @@
36e031625995b2f7baf7654d771ca8fb764a0085 bba6684d502ba1ecd9614d2470ec94296e3c07c2

View File

@@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope. ** All other code has file scope.
** **
** $Id: date.c,v 1.25 2004/05/26 16:54:42 drh Exp $ ** $Id: date.c,v 1.26 2004/05/26 23:25:31 drh Exp $
** **
** NOTES: ** NOTES:
** **
@@ -645,10 +645,10 @@ static int isDate(int argc, sqlite3_value **argv, DateTime *p){
int i; int i;
if( argc==0 ) return 1; if( argc==0 ) return 1;
if( SQLITE3_NULL==sqlite3_value_type(argv[0]) || if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ||
parseDateOrTime(sqlite3_value_data(argv[0]), p) ) return 1; parseDateOrTime(sqlite3_value_text(argv[0]), p) ) return 1;
for(i=1; i<argc; i++){ for(i=1; i<argc; i++){
if( SQLITE3_NULL==sqlite3_value_type(argv[i]) || if( SQLITE3_NULL==sqlite3_value_type(argv[i]) ||
parseModifier(sqlite3_value_data(argv[i]), p) ) return 1; parseModifier(sqlite3_value_text(argv[i]), p) ) return 1;
} }
return 0; return 0;
} }
@@ -761,7 +761,7 @@ static void strftimeFunc(
DateTime x; DateTime x;
int n, i, j; int n, i, j;
char *z; char *z;
const char *zFmt = sqlite3_value_data(argv[0]); const char *zFmt = sqlite3_value_text(argv[0]);
char zBuf[100]; char zBuf[100];
if( zFmt==0 || isDate(argc-1, argv+1, &x) ) return; if( zFmt==0 || isDate(argc-1, argv+1, &x) ) return;
for(i=0, n=1; zFmt[i]; i++, n++){ for(i=0, n=1; zFmt[i]; i++, n++){

View File

@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope. ** All other code has file scope.
** **
** $Id: func.c,v 1.57 2004/05/26 16:54:43 drh Exp $ ** $Id: func.c,v 1.58 2004/05/26 23:25:31 drh Exp $
*/ */
#include <ctype.h> #include <ctype.h>
#include <math.h> #include <math.h>
@@ -88,7 +88,7 @@ static void lengthFunc(
break; break;
} }
case SQLITE3_TEXT: { case SQLITE3_TEXT: {
const char *z = sqlite3_value_data(argv[0]); const char *z = sqlite3_value_text(argv[0]);
for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; } for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
sqlite3_result_int32(context, len); sqlite3_result_int32(context, len);
break; break;
@@ -108,7 +108,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
assert( argc==1 ); assert( argc==1 );
switch( sqlite3_value_type(argv[0]) ){ switch( sqlite3_value_type(argv[0]) ){
case SQLITE3_INTEGER: { case SQLITE3_INTEGER: {
sqlite3_result_int64(context, -sqlite3_value_int(argv[0])); sqlite3_result_int64(context, -sqlite3_value_int64(argv[0]));
break; break;
} }
case SQLITE3_NULL: { case SQLITE3_NULL: {
@@ -116,7 +116,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
break; break;
} }
default: { default: {
sqlite3_result_double(context, -sqlite3_value_float(argv[0])); sqlite3_result_double(context, -sqlite3_value_double(argv[0]));
break; break;
} }
} }
@@ -136,7 +136,7 @@ static void substrFunc(
int p1, p2, len; int p1, p2, len;
assert( argc==3 ); assert( argc==3 );
z = sqlite3_value_data(argv[0]); z = sqlite3_value_text(argv[0]);
if( z==0 ) return; if( z==0 ) return;
p1 = sqlite3_value_int(argv[1]); p1 = sqlite3_value_int(argv[1]);
p2 = sqlite3_value_int(argv[2]); p2 = sqlite3_value_int(argv[2]);
@@ -180,7 +180,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
if( n<0 ) n = 0; if( n<0 ) n = 0;
} }
if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return; if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
r = sqlite3_value_float(argv[0]); r = sqlite3_value_double(argv[0]);
sprintf(zBuf,"%.*f",n,r); sprintf(zBuf,"%.*f",n,r);
sqlite3_result_text(context, zBuf, -1, 1); sqlite3_result_text(context, zBuf, -1, 1);
} }
@@ -194,7 +194,7 @@ static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return; if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
z = sqliteMalloc(sqlite3_value_bytes(argv[0])); z = sqliteMalloc(sqlite3_value_bytes(argv[0]));
if( z==0 ) return; if( z==0 ) return;
strcpy(z, sqlite3_value_data(argv[0])); strcpy(z, sqlite3_value_text(argv[0]));
for(i=0; z[i]; i++){ for(i=0; z[i]; i++){
if( islower(z[i]) ) z[i] = toupper(z[i]); if( islower(z[i]) ) z[i] = toupper(z[i]);
} }
@@ -207,7 +207,7 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return; if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
z = sqliteMalloc(sqlite3_value_bytes(argv[0])); z = sqliteMalloc(sqlite3_value_bytes(argv[0]));
if( z==0 ) return; if( z==0 ) return;
strcpy(z, sqlite3_value_data(argv[0])); strcpy(z, sqlite3_value_text(argv[0]));
for(i=0; z[i]; i++){ for(i=0; z[i]; i++){
if( isupper(z[i]) ) z[i] = tolower(z[i]); if( isupper(z[i]) ) z[i] = tolower(z[i]);
} }
@@ -301,8 +301,8 @@ static void likeFunc(
int argc, int argc,
sqlite3_value **argv sqlite3_value **argv
){ ){
const unsigned char *zA = sqlite3_value_data(argv[0]); const unsigned char *zA = sqlite3_value_text(argv[0]);
const unsigned char *zB = sqlite3_value_data(argv[1]); const unsigned char *zB = sqlite3_value_text(argv[1]);
if( zA && zB ){ if( zA && zB ){
sqlite3_result_int32(context, sqlite3LikeCompare(zA, zB)); sqlite3_result_int32(context, sqlite3LikeCompare(zA, zB));
} }
@@ -318,8 +318,8 @@ static void likeFunc(
** is implemented as glob(A,B). ** is implemented as glob(A,B).
*/ */
static void globFunc(sqlite3_context *context, int arg, sqlite3_value **argv){ static void globFunc(sqlite3_context *context, int arg, sqlite3_value **argv){
const unsigned char *zA = sqlite3_value_data(argv[0]); const unsigned char *zA = sqlite3_value_text(argv[0]);
const unsigned char *zB = sqlite3_value_data(argv[1]); const unsigned char *zB = sqlite3_value_text(argv[1]);
if( zA && zB ){ if( zA && zB ){
sqlite3_result_int32(context, sqlite3GlobCompare(zA, zB)); sqlite3_result_int32(context, sqlite3GlobCompare(zA, zB));
} }
@@ -364,7 +364,6 @@ static void versionFunc(
** single-quote escapes. ** single-quote escapes.
*/ */
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
const char *zArg = sqlite3_value_data(argv[0]);
if( argc<1 ) return; if( argc<1 ) return;
switch( sqlite3_value_type(argv[0]) ){ switch( sqlite3_value_type(argv[0]) ){
case SQLITE3_NULL: { case SQLITE3_NULL: {
@@ -379,7 +378,7 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
case SQLITE3_BLOB: /*** FIX ME. Use a BLOB encoding ***/ case SQLITE3_BLOB: /*** FIX ME. Use a BLOB encoding ***/
case SQLITE3_TEXT: { case SQLITE3_TEXT: {
int i,j,n; int i,j,n;
const char *zArg = sqlite3_value_data(argv[0]); const char *zArg = sqlite3_value_text(argv[0]);
char *z; char *z;
for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
@@ -419,7 +418,7 @@ static void soundexFunc(sqlite3_context *context, int argc, sqlite3_value **argv
1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
}; };
assert( argc==1 ); assert( argc==1 );
zIn = sqlite3_value_data(argv[0]); zIn = sqlite3_value_text(argv[0]);
for(i=0; zIn[i] && !isalpha(zIn[i]); i++){} for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
if( zIn[i] ){ if( zIn[i] ){
zResult[0] = toupper(zIn[i]); zResult[0] = toupper(zIn[i]);
@@ -499,20 +498,20 @@ struct SumCtx {
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
SumCtx *p; SumCtx *p;
if( argc<1 ) return; if( argc<1 ) return;
p = sqlite3_get_context(context, sizeof(*p)); p = sqlite3_aggregate_context(context, sizeof(*p));
if( p && SQLITE3_NULL!=sqlite3_value_type(argv[0]) ){ if( p && SQLITE3_NULL!=sqlite3_value_type(argv[0]) ){
p->sum += sqlite3_value_float(argv[0]); p->sum += sqlite3_value_double(argv[0]);
p->cnt++; p->cnt++;
} }
} }
static void sumFinalize(sqlite3_context *context){ static void sumFinalize(sqlite3_context *context){
SumCtx *p; SumCtx *p;
p = sqlite3_get_context(context, sizeof(*p)); p = sqlite3_aggregate_context(context, sizeof(*p));
sqlite3_result_double(context, p ? p->sum : 0.0); sqlite3_result_double(context, p ? p->sum : 0.0);
} }
static void avgFinalize(sqlite3_context *context){ static void avgFinalize(sqlite3_context *context){
SumCtx *p; SumCtx *p;
p = sqlite3_get_context(context, sizeof(*p)); p = sqlite3_aggregate_context(context, sizeof(*p));
if( p && p->cnt>0 ){ if( p && p->cnt>0 ){
sqlite3_result_double(context, p->sum/(double)p->cnt); sqlite3_result_double(context, p->sum/(double)p->cnt);
} }
@@ -570,14 +569,14 @@ struct CountCtx {
*/ */
static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
CountCtx *p; CountCtx *p;
p = sqlite3_get_context(context, sizeof(*p)); p = sqlite3_aggregate_context(context, sizeof(*p));
if( (argc==0 || SQLITE3_NULL!=sqlite3_value_type(argv[0])) && p ){ if( (argc==0 || SQLITE3_NULL!=sqlite3_value_type(argv[0])) && p ){
p->n++; p->n++;
} }
} }
static void countFinalize(sqlite3_context *context){ static void countFinalize(sqlite3_context *context){
CountCtx *p; CountCtx *p;
p = sqlite3_get_context(context, sizeof(*p)); p = sqlite3_aggregate_context(context, sizeof(*p));
sqlite3_result_int32(context, p ? p->n : 0); sqlite3_result_int32(context, p ? p->n : 0);
} }
@@ -598,7 +597,7 @@ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv)
int max = 0; int max = 0;
int cmp = 0; int cmp = 0;
Mem *pArg = (Mem *)argv[0]; Mem *pArg = (Mem *)argv[0];
Mem *pBest = (Mem *)sqlite3_get_context(context, sizeof(*pBest)); Mem *pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return; if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
@@ -622,7 +621,7 @@ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv)
} }
static void minMaxFinalize(sqlite3_context *context){ static void minMaxFinalize(sqlite3_context *context){
sqlite3_value *pRes; sqlite3_value *pRes;
pRes = (sqlite3_value *)sqlite3_get_context(context, sizeof(Mem)); pRes = (sqlite3_value *)sqlite3_aggregate_context(context, sizeof(Mem));
if( pRes->flags ){ if( pRes->flags ){
sqlite3_result(context, pRes); sqlite3_result(context, pRes);
} }

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be ** other files are for internal use by SQLite and should not be
** accessed by users of the library. ** accessed by users of the library.
** **
** $Id: legacy.c,v 1.2 2004/05/26 02:04:57 danielk1977 Exp $ ** $Id: legacy.c,v 1.3 2004/05/26 23:25:31 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -90,7 +90,7 @@ int sqlite3_exec(
if( rc==SQLITE_ROW ){ if( rc==SQLITE_ROW ){
azVals = &azCols[nCol]; azVals = &azCols[nCol];
for(i=0; i<nCol; i++){ for(i=0; i<nCol; i++){
azVals[i] = (char *)sqlite3_column_data(pStmt, i); azVals[i] = (char *)sqlite3_column_text(pStmt, i);
} }
} }
if( xCallback(pArg, nCol, azVals, azCols) ){ if( xCallback(pArg, nCol, azVals, azCols) ){
@@ -133,5 +133,3 @@ exec_out:
return rc; return rc;
} }

View File

@@ -360,13 +360,13 @@ static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
MD5Context *p; MD5Context *p;
int i; int i;
if( argc<1 ) return; if( argc<1 ) return;
p = sqlite3_get_context(context, sizeof(*p)); p = sqlite3_aggregate_context(context, sizeof(*p));
if( p==0 ) return; if( p==0 ) return;
if( sqlite3_aggregate_count(context)==1 ){ if( sqlite3_aggregate_count(context)==1 ){
MD5Init(p); MD5Init(p);
} }
for(i=0; i<argc; i++){ for(i=0; i<argc; i++){
const char *zData = sqlite3_value_data(argv[i]); const char *zData = sqlite3_value_text(argv[i]);
if( zData ){ if( zData ){
MD5Update(p, zData, strlen(zData)); MD5Update(p, zData, strlen(zData));
} }
@@ -376,7 +376,7 @@ static void md5finalize(sqlite3_context *context){
MD5Context *p; MD5Context *p;
unsigned char digest[16]; unsigned char digest[16];
char zBuf[33]; char zBuf[33];
p = sqlite3_get_context(context, sizeof(*p)); p = sqlite3_aggregate_context(context, sizeof(*p));
MD5Final(digest,p); MD5Final(digest,p);
DigestToBase16(digest, zBuf); DigestToBase16(digest, zBuf);
sqlite3_result_text(context, zBuf, -1, 1); sqlite3_result_text(context, zBuf, -1, 1);
@@ -384,6 +384,3 @@ static void md5finalize(sqlite3_context *context){
void Md5_Register(sqlite *db){ void Md5_Register(sqlite *db){
sqlite3_create_function(db, "md5sum", -1, 0, 0, 0, 0, md5step, md5finalize); sqlite3_create_function(db, "md5sum", -1, 0, 0, 0, 0, md5step, md5finalize);
} }

View File

@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library ** This header file defines the interface that the SQLite library
** presents to client programs. ** presents to client programs.
** **
** @(#) $Id: sqlite.h.in,v 1.81 2004/05/26 16:54:44 drh Exp $ ** @(#) $Id: sqlite.h.in,v 1.82 2004/05/26 23:25:31 drh Exp $
*/ */
#ifndef _SQLITE_H_ #ifndef _SQLITE_H_
#define _SQLITE_H_ #define _SQLITE_H_
@@ -330,12 +330,14 @@ int sqlite3_get_table(
void sqlite3_free_table(char **result); void sqlite3_free_table(char **result);
/* /*
** The following routines are wrappers around sqlite3_exec() and ** The following routines are variants of the "sprintf()" from the
** sqlite3_get_table(). The only difference between the routines that ** standard C library. The resulting string is written into memory
** follow and the originals is that the second argument to the ** obtained from malloc() so that there is never a possiblity of buffer
** routines that follow is really a printf()-style format ** overflow. These routines also implement some additional formatting
** string describing the SQL to be executed. Arguments to the format ** options that are useful for constructing SQL statements.
** string appear at the end of the argument list. **
** The strings returned by these routines should be freed by calling
** sqlite3_free().
** **
** All of the usual printf formatting options apply. In addition, there ** All of the usual printf formatting options apply. In addition, there
** is a "%q" option. %q works like %s in that it substitutes a null-terminated ** is a "%q" option. %q works like %s in that it substitutes a null-terminated
@@ -367,50 +369,9 @@ void sqlite3_free_table(char **result);
** should always use %q instead of %s when inserting text into a string ** should always use %q instead of %s when inserting text into a string
** literal. ** literal.
*/ */
int sqlite3_exec_printf(
sqlite*, /* An open database */
const char *sqlFormat, /* printf-style format string for the SQL */
sqlite_callback, /* Callback function */
void *, /* 1st argument to callback function */
char **errmsg, /* Error msg written here */
... /* Arguments to the format string. */
);
int sqlite3_exec_vprintf(
sqlite*, /* An open database */
const char *sqlFormat, /* printf-style format string for the SQL */
sqlite_callback, /* Callback function */
void *, /* 1st argument to callback function */
char **errmsg, /* Error msg written here */
va_list ap /* Arguments to the format string. */
);
int sqlite3_get_table_printf(
sqlite*, /* An open database */
const char *sqlFormat, /* printf-style format string for the SQL */
char ***resultp, /* Result written to a char *[] that this points to */
int *nrow, /* Number of result rows written here */
int *ncolumn, /* Number of result columns written here */
char **errmsg, /* Error msg written here */
... /* Arguments to the format string */
);
int sqlite3_get_table_vprintf(
sqlite*, /* An open database */
const char *sqlFormat, /* printf-style format string for the SQL */
char ***resultp, /* Result written to a char *[] that this points to */
int *nrow, /* Number of result rows written here */
int *ncolumn, /* Number of result columns written here */
char **errmsg, /* Error msg written here */
va_list ap /* Arguments to the format string */
);
char *sqlite3_mprintf(const char*,...); char *sqlite3_mprintf(const char*,...);
char *sqlite3_vmprintf(const char*, va_list); char *sqlite3_vmprintf(const char*, va_list);
void sqlite3_free(char *z);
/*
** Windows systems should call this routine to free memory that
** is returned in the in the errmsg parameter of sqlite3_open() when
** SQLite is a DLL. For some reason, it does not work to call free()
** directly.
*/
void sqlite3_freemem(void *p);
/* /*
** Windows systems need functions to call to return the sqlite3_version ** Windows systems need functions to call to return the sqlite3_version
@@ -533,77 +494,17 @@ void sqlite3_progress_handler(sqlite*, int, int(*)(void*), void*);
void *sqlite3_commit_hook(sqlite*, int(*)(void*), void*); void *sqlite3_commit_hook(sqlite*, int(*)(void*), void*);
/* /*
** Open an encrypted SQLite database. If pKey==0 or nKey==0, this routine ** Open the sqlite database file "filename". The "filename" is UTF-8
** is the same as sqlite3_open(). ** encoded for sqlite3_open() and UTF-16 encoded in the native byte order
** for sqlite3_open16(). An sqlite3* handle is returned in *ppDb, even
** if an error occurs. If the database is opened (or created) successfully,
** then SQLITE_OK is returned. Otherwise an error code is returned. The
** sqlite3_errmsg() or sqlite3_errmsg16() routines can be used to obtain
** an English language description of the error.
** **
** The code to implement this API is not available in the public release ** If the database file does not exist, then a new database is created.
** of SQLite. ** The encoding for the database is UTF-8 if sqlite3_open() is called and
*/ ** UTF-16 if sqlite3_open16 is used.
sqlite *sqlite3_open_encrypted(
const char *zFilename, /* Name of the encrypted database */
const void *pKey, /* Pointer to the key */
int nKey, /* Number of bytes in the key */
int *pErrcode, /* Write error code here */
char **pzErrmsg /* Write error message here */
);
/*
** Change the key on an open database. If the current database is not
** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
** database is decrypted.
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
int sqlite_rekey(
sqlite *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
/*
** Encode a binary buffer "in" of size n bytes so that it contains
** no instances of characters '\'' or '\000'. The output is
** null-terminated and can be used as a string value in an INSERT
** or UPDATE statement. Use sqlite_decode_binary() to convert the
** string back into its original binary.
**
** The result is written into a preallocated output buffer "out".
** "out" must be able to hold at least 2 +(257*n)/254 bytes.
** In other words, the output will be expanded by as much as 3
** bytes for every 254 bytes of input plus 2 bytes of fixed overhead.
** (This is approximately 2 + 1.0118*n or about a 1.2% size increase.)
**
** The return value is the number of characters in the encoded
** string, excluding the "\000" terminator.
**
** If out==NULL then no output is generated but the routine still returns
** the number of characters that would have been generated if out had
** not been NULL.
*/
int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
/*
** Decode the string "in" into binary data and write it into "out".
** This routine reverses the encoding created by sqlite_encode_binary().
** The output will always be a few bytes less than the input. The number
** of bytes of output is returned. If the input is not a well-formed
** encoding, -1 is returned.
**
** The "in" and "out" parameters may point to the same buffer in order
** to decode a string in place.
*/
int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
/*
** Open the sqlite database file "filename", where "filename" is UTF-8
** encoded. An sqlite3* handle is returned in *ppDb, even if an error
** occurs. If the database is opened (or created) successfully, then
** SQLITE_OK is returned. Otherwise an error code is returned and the
** sqlite3_errmsg() function may be used to obtain an English language
** explanation of the error.
**
** If the database file does not exist, then a new database is created
** using UTF-8 text encoding.
** **
** Whether or not an error occurs when it is opened, resources associated ** Whether or not an error occurs when it is opened, resources associated
** with the sqlite3* handle should be released by passing it to ** with the sqlite3* handle should be released by passing it to
@@ -614,22 +515,6 @@ int sqlite3_open(
sqlite3 **ppDb, /* OUT: SQLite db handle */ sqlite3 **ppDb, /* OUT: SQLite db handle */
const char **args /* Null terminated array of option strings */ const char **args /* Null terminated array of option strings */
); );
/*
** Open the sqlite database file "filename", where "filename" is native
** byte order UTF-16 encoded. An sqlite3* handle is returned in *ppDb, even
** if an error occurs. If the database is opened (or created) successfully,
** then SQLITE_OK is returned. Otherwise an error code is returned and the
** sqlite3_errmsg() function may be used to obtain an English language
** explanation of the error.
**
** If the database file does not exist, then a new database is created
** using UTF-16 text encoding in the machines native byte order.
**
** Whether or not an error occurs when it is opened, resources associated
** with the sqlite3* handle should be released by passing it to
** sqlite3_close() when it is no longer required.
*/
int sqlite3_open16( int sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */ const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb, /* OUT: SQLite db handle */ sqlite3 **ppDb, /* OUT: SQLite db handle */
@@ -719,6 +604,35 @@ int sqlite3_prepare16(
const void **pzTail /* OUT: Pointer to unused portion of zSql */ const void **pzTail /* OUT: Pointer to unused portion of zSql */
); );
/*
** In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(),
** one or more literals can be replace by a wildcard "?" or ":N:" where
** N is an integer. These value of these wildcard literals can be set
** using the routines listed below.
**
** In every case, the first parameter is a pointer to the sqlite3_stmt
** structure returned from sqlite3_prepare(). The second parameter is the
** index of the wildcard. The first "?" has an index of 1. ":N:" wildcards
** use the index N.
**
** When the eCopy parameter is true, a copy of the value is made into
** memory obtained and managed by SQLite. When eCopy is false, SQLite
** assumes that the value is a constant and just stores a pointer to the
** value without making a copy.
**
** The sqlite3_bind_* routine must be called before sqlite3_step() after
** an sqlite3_prepare() or sqlite3_reset(). Unbound wildcards are interpreted
** as NULL.
*/
void sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, int eCopy);
void sqlite3_bind_double(sqlite3_stmt*, int, double);
void sqlite3_bind_int(sqlite3_stmt*, int, int);
void sqlite3_bind_int64(sqlite3_stmt*, int, long long int);
void sqlite3_bind_null(sqlite3_stmt*, int);
void sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, int eCopy);
void sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, int eCopy);
void sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
/* /*
** Return the number of columns in the result set returned by the compiled ** Return the number of columns in the result set returned by the compiled
** SQL statement. This routine returns 0 if pStmt is an SQL statement ** SQL statement. This routine returns 0 if pStmt is an SQL statement
@@ -729,15 +643,10 @@ int sqlite3_column_count(sqlite3_stmt *pStmt);
/* /*
** The first parameter is a compiled SQL statement. This function returns ** The first parameter is a compiled SQL statement. This function returns
** the column heading for the Nth column of that statement, where N is the ** the column heading for the Nth column of that statement, where N is the
** second function parameter. The string returned is UTF-8 encoded. ** second function parameter. The string returned is UTF-8 for
** sqlite3_column_name() and UTF-16 for sqlite3_column_name16().
*/ */
const char *sqlite3_column_name(sqlite3_stmt*,int); const char *sqlite3_column_name(sqlite3_stmt*,int);
/*
** The first parameter is a compiled SQL statement. This function returns
** the column heading for the Nth column of that statement, where N is the
** second function parameter. The string returned is UTF-16 encoded.
*/
const void *sqlite3_column_name16(sqlite3_stmt*,int); const void *sqlite3_column_name16(sqlite3_stmt*,int);
/* /*
@@ -768,131 +677,18 @@ const char *sqlite3_column_decltype(sqlite3_stmt *, int i);
** column, then a NULL pointer is returned. The returned string is always ** column, then a NULL pointer is returned. The returned string is always
** UTF-16 encoded. For example, in the database schema: ** UTF-16 encoded. For example, in the database schema:
** **
** CREATE TABLE t1(c1 VARINT); ** CREATE TABLE t1(c1 INTEGER);
** **
** And the following statement compiled: ** And the following statement compiled:
** **
** SELECT c1 + 1, 0 FROM t1; ** SELECT c1 + 1, 0 FROM t1;
** **
** Then this routine would return the string "VARIANT" for the second ** Then this routine would return the string "INTEGER" for the second
** result column (i==1), and a NULL pointer for the first result column ** result column (i==1), and a NULL pointer for the first result column
** (i==0). ** (i==0).
*/ */
const void *sqlite3_column_decltype16(sqlite3_stmt*,int); const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
/*
** This routine is used to bind a 32-bit integer value to a variable
** in an SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously
** obtained from a call to sqlite3_prepare(). The second parameter "i"
** determines the parameter to bind the value "iValue" to.
*/
int sqlite3_bind_int32(sqlite3_stmt*, int i, int iValue);
/*
** This routine is used to bind a 64-bit integer value to a variable
** in an SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously
** obtained from a call to sqlite3_prepare(). The second parameter "i"
** determines the parameter to bind the value "iValue" to.
*/
int sqlite3_bind_int64(sqlite3_stmt*, int i, long long int iValue);
/*
** This routine is used to bind a real (floating point) value to a variable
** in an SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_prepare(). The second parameter "i" determines
** the parameter to bind the value "iValue" to. Internally, SQLite will
** manipulate the value as a 64-bit IEEE float.
*/
int sqlite3_bind_double(sqlite3_stmt*, int i, double iValue);
/*
** This routine is used to bind a NULL value to a variable in an SQL
** statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_prepare(). The second parameter "i" determines
** the parameter to bind the NULL value to.
*/
int sqlite3_bind_null(sqlite3_stmt*, int i);
/*
** This routine is used to bind a UTF-8 string value to a variable in an
** SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_prepare(). The second parameter "i" determines
** the parameter to bind the value to. Parameter three "z" is a pointer
** to the UTF-8 string.
**
** The fourth "n" parameter is the number of bytes (not characters) in the
** string pointed to by "z". "n" may or may not include any nul terminator
** character. If "n" is less than zero, then SQLite assumes that "z" is
** a nul terminated string.
**
** If paramater "eCopy" is true, then SQLite makes a copy of the string
** pointed to by "z". If "eCopy" is false, then SQLite stores a pointer to
** the original string data. In this case the caller must ensure that the
** string data remains stable until after the SQL statement has been
** finalised or another value bound to variable "i".
*/
int sqlite3_bind_text(sqlite3_stmt*, int i, const char* z, int n, int eCopy);
/*
** This routine is used to bind a UTF-16 string value to a variable in an
** SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_prepare(). The second parameter "i" determines
** the parameter to bind the value to. Parameter three "z" is a pointer to
** the UTF-16 string. If the string does not begin with a byte-order-mark,
** it is assumed to be encoded in the native byte order of the machine.
**
** The fourth "n" parameter is the number of bytes (not characters) in the
** string pointed to by "z". "n" may or may not include any nul terminator
** character. If "n" is less than zero, then SQLite assumes that "z" is
** terminated by a pair of 0x00 characters.
**
** If paramater "eCopy" is true, then SQLite makes a copy of the string
** pointed to by "z". If "eCopy" is false, then SQLite stores a pointer to
** the original string data. In this case the caller must ensure that the
** string data remains stable until after the SQL statement has been
** finalised or another value bound to variable "i".
*/
int sqlite3_bind_text16(sqlite3_stmt*, int i, const void *z, int, int eCopy);
/*
** This routine is used to bind a blob value to a variable in an
** SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_prepare(). The second parameter "i" determines
** the parameter to bind the value to. Parameter three "z" is a pointer to
** the blob of data.
**
** The fourth "n" parameter is the number of bytes in the blob pointed to
** by "z". "n" may not be less than zero.
**
** If paramater "eCopy" is true, then SQLite makes a copy of the blob
** pointed to by "z". If "eCopy" is false, then SQLite stores a pointer to
** the original blob data. In this case the caller must ensure that the
** blob data remains stable until after the SQL statement has been
** finalised or another value bound to variable "i".
*/
int sqlite3_bind_blob(sqlite3_stmt*, int i, const void *z, int n, int eCopy);
/* /*
** After an SQL query has been compiled with a call to either ** After an SQL query has been compiled with a call to either
** sqlite3_prepare() or sqlite3_prepare16(), then this function must be ** sqlite3_prepare() or sqlite3_prepare16(), then this function must be
@@ -938,108 +734,82 @@ int sqlite3_step(sqlite3_stmt*);
*/ */
int sqlite3_data_count(sqlite3_stmt *pStmt); int sqlite3_data_count(sqlite3_stmt *pStmt);
#define SQLITE3_INTEGER 1 /*
#define SQLITE3_FLOAT 2 ** Values are stored in the database in one of the following fundamental
#define SQLITE3_TEXT 3 ** types.
#define SQLITE3_BLOB 4 */
#define SQLITE3_NULL 5 #define SQLITE_INTEGER 1
#define SQLITE_FLOAT 2
#define SQLITE_TEXT 3
#define SQLITE_BLOB 4
#define SQLITE_NULL 5
/* /*
** The first parameter is a compiled SQL statement for which the most ** The next group of routines returns information about the information
** recent call to sqlite3_step() has returned SQLITE_ROW. This routine ** in a single column of the current result row of a query. In every
** retrieves the type of the Nth column of the current row, where ** case the first parameter is a pointer to the SQL statement that is being
** N is the second function parameter. ** executed (the sqlite_stmt* that was returned from sqlite3_prepare()) and
** the second argument is the index of the column for which information
** should be returned. iCol is zero-indexed. The left-most column as an
** index of 0.
** **
** The value type is one of SQLITE3_INTEGER, SQLITE3_FLOAT, SQLITE3_TEXT, ** If the SQL statement is not currently point to a valid row, or if the
** SQLITE3_BLOB and SQLITE3_NULL. ** the colulmn index is out of range, the result is undefined.
**
** These routines attempt to convert the value where appropriate. For
** example, if the internal representation is FLOAT and a text result
** is requested, sprintf() is used internally to do the conversion
** automatically. The following table details the conversions that
** are applied:
**
** Internal Type Requested Type Conversion
** ------------- -------------- --------------------------
** NULL INTEGER Result is 0
** NULL FLOAT Result is 0.0
** NULL TEXT Result is an empty string
** NULL BLOB Result is a zero-length BLOB
** INTEGER FLOAT Convert from integer to float
** INTEGER TEXT ASCII rendering of the integer
** INTEGER BLOB Same as for INTEGER->TEXT
** FLOAT INTEGER Convert from float to integer
** FLOAT TEXT ASCII rendering of the float
** FLOAT BLOB Same as FLOAT->TEXT
** TEXT INTEGER Use atoi()
** TEXT FLOAT Use atof()
** TEXT BLOB No change
** BLOB INTEGER Convert to TEXT then use atoi()
** BLOB FLOAT Convert to TEXT then use atof()
** BLOB TEXT Add a \000 terminator if needed
**
** The following access routines are provided:
**
** _type() Return the datatype of the result. This is one of
** SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB,
** or SQLITE_NULL.
** _blob() Return the value of a BLOB.
** _bytes() Return the number of bytes in a BLOB value or the number
** of bytes in a TEXT value represented as UTF-8. The \000
** terminator is included in the byte count for TEXT values.
** _bytes16() Return the number of bytes in a BLOB value or the number
** of bytes in a TEXT value represented as UTF-16. The \u0000
** terminator is included in the byte count for TEXT values.
** _double() Return a FLOAT value.
** _int() Return an INTEGER value in the host computer's native
** integer representation. This might be either a 32- or 64-bit
** integer depending on the host.
** _int64() Return an INTEGER value as a 64-bit signed integer.
** _text() Return the value as UTF-8 text.
** _text16() Return the value as UTF-16 text.
*/ */
int sqlite3_column_type(sqlite3_stmt *pStmt, int i); void *sqlite3_column_blob(sqlite3_stmt*, int iCol)
int sqlite3_column_bytes(sqlite3_stmt*, int iCol)
/* int sqlite3_column_bytes16(sqlite3_stmt*, int iCol)
** The first parameter is a compiled SQL statement for which the most double sqlite3_column_double(sqlite3_stmt*, int iCol)
** recent call to sqlite3_step() has returned SQLITE_ROW. This routine int sqlite3_column_int(sqlite3_stmt*, int iCol)
** retrieves the value of the Nth column of the current row, where long long int sqlite3_column_int64(sqlite3_stmt*, int iCol)
** N is the second function parameter. const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol)
** const void *sqlite3_column_text16(sqlite3_stmt*, int iCol)
** The value returned depends on the type of the SQL column value, as int sqlite3_column_type(sqlite3_stmt*, int iCol);
** returned by sqlite3_column_type():
**
** SQLITE3_NULL A Null pointer.
** SQLITE3_INTEGER String representation of the integer, UTF-8 encoded.
** SQLITE3_FLOAT String representation of the real, UTF-8 encoded.
** SQLITE3_TEXT The string UTF-8 encoded.
** SQLITE3_BLOB A pointer to the blob of data.
*/
const unsigned char *sqlite3_column_data(sqlite3_stmt*,int);
/*
** The first parameter is a compiled SQL statement for which the most
** recent call to sqlite3_step() has returned SQLITE_ROW. This routine
** retrieves the value of the Nth column of the current row, where
** N is the second function parameter.
**
** The value returned depends on the type of the SQL column value, as
** returned by sqlite3_column_type():
**
** SQLITE3_NULL A Null pointer.
** SQLITE3_INTEGER String representation of the integer, UTF-16 encoded.
** SQLITE3_FLOAT String representation of the real, UTF-16 encoded.
** SQLITE3_TEXT The string UTF-16 encoded.
** SQLITE3_BLOB A pointer to the blob of data.
*/
const void *sqlite3_column_data16(sqlite3_stmt*,int);
/*
** The first parameter is a compiled SQL statement for which the most
** recent call to sqlite3_step() has returned SQLITE_ROW. This routine
** retrieves the length of the data in bytes returned by the
** sqlite3_column_data() routine for the same second parameter value.
**
** If sqlite3_column_data() returns a UTF-8 string, then the length
** returned by this function includes the nul terminator character at the
** end of the UTF-8 string.
*/
int sqlite3_column_bytes(sqlite3_stmt*,int);
/*
** The first parameter is a compiled SQL statement for which the most
** recent call to sqlite3_step() has returned SQLITE_ROW. This routine
** retrieves the length of the data in bytes returned by the
** sqlite3_column_data() routine for the same second parameter value.
**
** If sqlite3_column_data() returns a UTF-16 string, then the length
** returned by this function includes the nul terminator character (two
** bytes) at the end of the UTF-16 string.
*/
int sqlite3_column_bytes16(sqlite3_stmt *, int);
/*
** The first parameter is a compiled SQL statement for which the most
** recent call to sqlite3_step() has returned SQLITE_ROW. This routine
** retrieves the value of the Nth column of the current row, where
** N is the second function parameter as an integer.
**
** SQLITE3_NULL 0
** SQLITE3_INTEGER The integer value.
** SQLITE3_FLOAT The integer component of the real (2^63 if too large)
** SQLITE3_TEXT Integer conversion of string, or 0
** SQLITE3_BLOB 0
*/
long long int sqlite3_column_int(sqlite3_stmt*,int);
/*
** The first parameter is a compiled SQL statement for which the most
** recent call to sqlite3_step() has returned SQLITE_ROW. This routine
** retrieves the value of the Nth column of the current row, where
** N is the second function parameter as an integer.
**
** SQLITE3_NULL 0.0
** SQLITE3_INTEGER The value of the integer. Some rounding may occur.
** SQLITE3_FLOAT The value of the float.
** SQLITE3_TEXT Real number conversion of string, or 0.0
** SQLITE3_BLOB 0.0
*/
double sqlite3_column_float(sqlite3_stmt*,int);
/* /*
** The sqlite3_finalize() function is called to delete a compiled ** The sqlite3_finalize() function is called to delete a compiled
@@ -1131,78 +901,24 @@ int sqlite3_create_function16(
*/ */
int sqlite3_aggregate_count(sqlite3_context*); int sqlite3_aggregate_count(sqlite3_context*);
/* /*
** Return the type of the sqlite3_value* passed as the first argument. ** The next group of routines returns information about parameters to
** The type is one of SQLITE3_NULL, SQLITE3_INTEGER, SQLITE3_FLOAT, ** a user-defined function. Function implementations use these routines
** SQLITE3_TEXT or SQLITE3_BLOB. ** to access their parameters. These routines are the same as the
** sqlite3_column_* routines except that these routines take a single
** sqlite3_value* pointer instead of an sqlite3_stmt* and an integer
** column number.
*/ */
void *sqlite3_value_blob(sqlite3_value*)
int sqlite3_value_bytes(sqlite3_value*)
int sqlite3_value_bytes16(sqlite3_value*)
double sqlite3_value_double(sqlite3_value*)
int sqlite3_value_int(sqlite3_value*)
long long int sqlite3_value_int64(sqlite3_value*)
const unsigned char *sqlite3_value_text(sqlite3_value*)
const void *sqlite3_value_text16(sqlite3_value*)
int sqlite3_value_type(sqlite3_value*); int sqlite3_value_type(sqlite3_value*);
/*
** Return the value of the sqlite3_value* passed as the first argument.
** The value returned depends on the type of the value, as returned by
** sqlite3_value_type():
**
** SQLITE3_NULL A Null pointer.
** SQLITE3_INTEGER String representation of the integer, UTF-8 encoded.
** SQLITE3_FLOAT String representation of the real, UTF-8 encoded.
** SQLITE3_TEXT The string UTF-8 encoded.
** SQLITE3_BLOB A pointer to the blob of data.
*/
const unsigned char *sqlite3_value_data(sqlite3_value*);
/*
** Return the number of bytes in the string or blob returned by a call
** to sqlite3_value_data() on the same sqlite3_value* object.
*/
int sqlite3_value_bytes(sqlite3_value*);
/*
** Return the value of the sqlite3_value* passed as the first argument.
** The value returned depends on the type of the value, as returned by
** sqlite3_value_type():
**
** SQLITE3_NULL A Null pointer.
** SQLITE3_INTEGER String representation of the integer, UTF-16 encoded.
** SQLITE3_FLOAT String representation of the real, UTF-16 encoded.
** SQLITE3_TEXT The string UTF-16 encoded.
** SQLITE3_BLOB A pointer to the blob of data.
*/
const void *sqlite3_value_data16(sqlite3_value*);
/*
** Return the number of bytes in the string or blob returned by a call
** to sqlite3_value_data16() on the same sqlite3_value* object.
*/
int sqlite3_value_bytes16(sqlite3_value*);
/*
** Return the value of the sqlite3_value* passed as the first argument.
** The value returned depends on the type of the value, as returned by
** sqlite3_value_type():
**
** SQLITE3_NULL 0
** SQLITE3_INTEGER The integer value.
** SQLITE3_FLOAT The integer component of the real (2^63 if too large)
** SQLITE3_TEXT Integer conversion of string, or 0
** SQLITE3_BLOB 0
*/
long long int sqlite3_value_int(sqlite3_value*);
/*
** Return the value of the sqlite3_value* passed as the first argument.
** The value returned depends on the type of the value, as returned by
** sqlite3_value_type():
**
** SQLITE3_NULL 0.0
** SQLITE3_INTEGER The value of the integer. Some rounding may occur.
** SQLITE3_FLOAT The value of the float.
** SQLITE3_TEXT Real number conversion of string, or 0.0
** SQLITE3_BLOB 0.0
*/
double sqlite3_value_float(sqlite3_value*);
/* /*
** Aggregate functions use the following routine to allocate ** Aggregate functions use the following routine to allocate
** a structure for storing their state. The first time this routine ** a structure for storing their state. The first time this routine
@@ -1213,7 +929,7 @@ double sqlite3_value_float(sqlite3_value*);
** **
** The buffer allocated is freed automatically by SQLite. ** The buffer allocated is freed automatically by SQLite.
*/ */
void *sqlite3_get_context(sqlite3_context*, int nBytes); void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/* /*
** The pUserData parameter to the sqlite3_create_function() and ** The pUserData parameter to the sqlite3_create_function() and
@@ -1224,89 +940,19 @@ void *sqlite3_get_context(sqlite3_context*, int nBytes);
void *sqlite3_user_data(sqlite3_context*); void *sqlite3_user_data(sqlite3_context*);
/* /*
** The following three functions may be called from within a user-defined ** User-defined functions invoke the following routines in order to
** function callback or a user-defined aggregate finalizer callback. The ** set their return value.
** 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); void sqlite3_result_blob(sqlite3_context*, const void*, int n, int eCopy);
void sqlite3_result_double(sqlite3_context*, double);
/*
** 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_error(sqlite3_context*, const char*, int);
void sqlite3_result_error16(sqlite3_context*, const void*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int);
void sqlite3_result_int(sqlite3_context*, int);
/* void sqlite3_result_int64(sqlite3_context*, long long int);
** Copy a function parameter into the result of the function. void sqlite3_result_null(sqlite3_context*);
*/ void sqlite3_result_text(sqlite3_context*, const char*, int n, int eCopy);
void sqlite3_result(sqlite3_context*, sqlite3_value*); void sqlite3_result_text16(sqlite3_context*, const void*, int n, int eCopy);
void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
#ifdef __cplusplus #ifdef __cplusplus
} /* End of the 'extern "C"' block */ } /* End of the 'extern "C"' block */

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** A TCL Interface to SQLite ** A TCL Interface to SQLite
** **
** $Id: tclsqlite.c,v 1.72 2004/05/26 16:54:46 drh Exp $ ** $Id: tclsqlite.c,v 1.73 2004/05/26 23:25:31 drh Exp $
*/ */
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
@@ -391,7 +391,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
if( SQLITE3_NULL==sqlite3_value_type(argv[i]) ){ if( SQLITE3_NULL==sqlite3_value_type(argv[i]) ){
Tcl_DStringAppendElement(&cmd, ""); Tcl_DStringAppendElement(&cmd, "");
}else{ }else{
Tcl_DStringAppendElement(&cmd, sqlite3_value_data(argv[i])); Tcl_DStringAppendElement(&cmd, sqlite3_value_text(argv[i]));
} }
} }
rc = Tcl_Eval(p->interp, Tcl_DStringValue(&cmd)); rc = Tcl_Eval(p->interp, Tcl_DStringValue(&cmd));

View File

@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated ** is not included in the SQLite library. It is used for automated
** testing of the SQLite library. ** testing of the SQLite library.
** **
** $Id: test1.c,v 1.58 2004/05/26 13:27:00 danielk1977 Exp $ ** $Id: test1.c,v 1.59 2004/05/26 23:25:31 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "tcl.h" #include "tcl.h"
@@ -300,7 +300,7 @@ static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
int i; int i;
for(i=0; i<argc; i++){ for(i=0; i<argc; i++){
if( SQLITE3_NULL!=sqlite3_value_type(argv[i]) ){ if( SQLITE3_NULL!=sqlite3_value_type(argv[i]) ){
sqlite3_result_text(context, sqlite3_value_data(argv[i]), -1, 1); sqlite3_result_text(context, sqlite3_value_text(argv[i]), -1, 1);
break; break;
} }
} }
@@ -373,7 +373,7 @@ static void sqlite3ExecFunc(
struct dstr x; struct dstr x;
memset(&x, 0, sizeof(x)); memset(&x, 0, sizeof(x));
sqlite3_exec((sqlite*)sqlite3_user_data(context), sqlite3_exec((sqlite*)sqlite3_user_data(context),
sqlite3_value_data(argv[0]), sqlite3_value_text(argv[0]),
execFuncCallback, &x, 0); execFuncCallback, &x, 0);
sqlite3_result_text(context, x.z, x.nUsed, 1); sqlite3_result_text(context, x.z, x.nUsed, 1);
sqliteFree(x.z); sqliteFree(x.z);
@@ -423,14 +423,14 @@ struct CountCtx {
}; };
static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
CountCtx *p; CountCtx *p;
p = sqlite3_get_context(context, sizeof(*p)); p = sqlite3_aggregate_context(context, sizeof(*p));
if( (argc==0 || SQLITE3_NULL!=sqlite3_value_type(argv[0]) ) && p ){ if( (argc==0 || SQLITE3_NULL!=sqlite3_value_type(argv[0]) ) && p ){
p->n++; p->n++;
} }
} }
static void countFinalize(sqlite3_context *context){ static void countFinalize(sqlite3_context *context){
CountCtx *p; CountCtx *p;
p = sqlite3_get_context(context, sizeof(*p)); p = sqlite3_aggregate_context(context, sizeof(*p));
sqlite3_result_int32(context, p ? p->n : 0); sqlite3_result_int32(context, p ? p->n : 0);
} }
@@ -645,8 +645,8 @@ static int sqlite_abort(
*/ */
static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
while( argc>=2 ){ while( argc>=2 ){
const char *zArg0 = sqlite3_value_data(argv[0]); const char *zArg0 = sqlite3_value_text(argv[0]);
const char *zArg1 = sqlite3_value_data(argv[1]); const char *zArg1 = sqlite3_value_text(argv[1]);
if( zArg0==0 ){ if( zArg0==0 ){
sqlite3_result_error(context, "first argument to test function " sqlite3_result_error(context, "first argument to test function "
"may not be NULL", -1); "may not be NULL", -1);
@@ -1316,11 +1316,11 @@ static int test_step(
} }
/* /*
** Usage: sqlite3_column_data STMT column ** Usage: sqlite3_column_text STMT column
** **
** Advance the statement to the next row. ** Advance the statement to the next row.
*/ */
static int test_column_data( static int test_column_text(
void * clientData, void * clientData,
Tcl_Interp *interp, Tcl_Interp *interp,
int objc, int objc,
@@ -1341,9 +1341,9 @@ static int test_column_data(
if( SQLITE3_BLOB==sqlite3_column_type(pStmt, col) ){ if( SQLITE3_BLOB==sqlite3_column_type(pStmt, col) ){
int len = sqlite3_column_bytes(pStmt, col); int len = sqlite3_column_bytes(pStmt, col);
pRet = Tcl_NewByteArrayObj(sqlite3_column_data(pStmt, col), len); pRet = Tcl_NewByteArrayObj(sqlite3_column_text(pStmt, col), len);
}else{ }else{
pRet = Tcl_NewStringObj(sqlite3_column_data(pStmt, col), -1); pRet = Tcl_NewStringObj(sqlite3_column_text(pStmt, col), -1);
} }
Tcl_SetObjResult(interp, pRet); Tcl_SetObjResult(interp, pRet);
@@ -1351,11 +1351,11 @@ static int test_column_data(
} }
/* /*
** Usage: sqlite3_column_data16 STMT column ** Usage: sqlite3_column_text16 STMT column
** **
** Advance the statement to the next row. ** Advance the statement to the next row.
*/ */
static int test_column_data16( static int test_column_text16(
void * clientData, void * clientData,
Tcl_Interp *interp, Tcl_Interp *interp,
int objc, int objc,
@@ -1376,7 +1376,7 @@ static int test_column_data16(
if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
len = sqlite3_column_bytes16(pStmt, col); len = sqlite3_column_bytes16(pStmt, col);
pRet = Tcl_NewByteArrayObj(sqlite3_column_data16(pStmt, col), len); pRet = Tcl_NewByteArrayObj(sqlite3_column_text16(pStmt, col), len);
Tcl_SetObjResult(interp, pRet); Tcl_SetObjResult(interp, pRet);
return TCL_OK; return TCL_OK;
@@ -1663,8 +1663,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_finalize", (Tcl_ObjCmdProc*)test_finalize }, { "sqlite3_finalize", (Tcl_ObjCmdProc*)test_finalize },
{ "sqlite3_reset", (Tcl_ObjCmdProc*)test_reset }, { "sqlite3_reset", (Tcl_ObjCmdProc*)test_reset },
{ "sqlite3_step", (Tcl_ObjCmdProc*)test_step}, { "sqlite3_step", (Tcl_ObjCmdProc*)test_step},
{ "sqlite3_column_data", (Tcl_ObjCmdProc*)test_column_data }, { "sqlite3_column_text", (Tcl_ObjCmdProc*)test_column_text },
{ "sqlite3_column_data16", (Tcl_ObjCmdProc*)test_column_data16 }, { "sqlite3_column_text16", (Tcl_ObjCmdProc*)test_column_text16 },
{ "sqlite3_column_count", (Tcl_ObjCmdProc*)test_column_count }, { "sqlite3_column_count", (Tcl_ObjCmdProc*)test_column_count },
{ "sqlite3_column_name", (Tcl_ObjCmdProc*)test_column_name }, { "sqlite3_column_name", (Tcl_ObjCmdProc*)test_column_name },
{ "sqlite3_column_name16", (Tcl_ObjCmdProc*)test_column_name16 }, { "sqlite3_column_name16", (Tcl_ObjCmdProc*)test_column_name16 },

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Code for testing the the SQLite library in a multithreaded environment. ** Code for testing the the SQLite library in a multithreaded environment.
** **
** $Id: test4.c,v 1.7 2004/05/26 02:04:57 danielk1977 Exp $ ** $Id: test4.c,v 1.8 2004/05/26 23:25:31 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "tcl.h" #include "tcl.h"
@@ -498,7 +498,7 @@ static void do_step(Thread *p){
if( p->rc==SQLITE_ROW ){ if( p->rc==SQLITE_ROW ){
p->argc = sqlite3_column_count(p->pStmt); p->argc = sqlite3_column_count(p->pStmt);
for(i=0; i<sqlite3_data_count(p->pStmt); i++){ for(i=0; i<sqlite3_data_count(p->pStmt); i++){
p->argv[i] = sqlite3_column_data(p->pStmt, i); p->argv[i] = sqlite3_column_text(p->pStmt, i);
} }
for(i=0; i<p->argc; i++){ for(i=0; i<p->argc; i++){
p->colv[i] = sqlite3_column_name(p->pStmt, i); p->colv[i] = sqlite3_column_name(p->pStmt, i);
@@ -648,6 +648,3 @@ int Sqlitetest4_Init(Tcl_Interp *interp){
#else #else
int Sqlitetest4_Init(Tcl_Interp *interp){ return TCL_OK; } int Sqlitetest4_Init(Tcl_Interp *interp){ return TCL_OK; }
#endif /* OS_UNIX */ #endif /* OS_UNIX */

File diff suppressed because it is too large Load Diff

View File

@@ -137,31 +137,6 @@ struct Mem {
}; };
typedef struct Mem 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 (or blob if enc==0).
*/
#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) \
if( ((p)->flags&MEM_Str) && !((p)->flags&MEM_Term) ) sqlite3VdbeMemNulTerminate(p);
/* One or more of the following flags are set to indicate the valid /* One or more of the following flags are set to indicate the valid
** representations of the value stored in the Mem struct. ** representations of the value stored in the Mem struct.
** **
@@ -215,8 +190,8 @@ if( ((p)->flags&MEM_Str) && !((p)->flags&MEM_Term) ) sqlite3VdbeMemNulTerminate(
** When a user-defined function is called (see OP_Function), the Mem* ** When a user-defined function is called (see OP_Function), the Mem*
** objects that store the argument values for the function call are ** objects that store the argument values for the function call are
** passed to the user-defined function routine cast to sqlite3_value*. ** passed to the user-defined function routine cast to sqlite3_value*.
** The user routine may then call sqlite3_value_data() or ** The user routine may then call sqlite3_value_text() or
** sqlite3_value_data16() to request a UTF-8 or UTF-16 string. If the ** sqlite3_value_text16() to request a UTF-8 or UTF-16 string. If the
** string representation currently stored in Mem.z is not the requested ** string representation currently stored in Mem.z is not the requested
** encoding, then a translation occurs. To keep track of things, the ** encoding, then a translation occurs. To keep track of things, the
** MEM_Utf* flags are set correctly for the database encoding before a ** MEM_Utf* flags are set correctly for the database encoding before a
@@ -228,7 +203,7 @@ if( ((p)->flags&MEM_Str) && !((p)->flags&MEM_Term) ) sqlite3VdbeMemNulTerminate(
** internally as Mem* objects. Before sqlite3_step() returns, the MEM_Utf* ** internally as Mem* objects. Before sqlite3_step() returns, the MEM_Utf*
** flags are set correctly for the database encoding. A translation may ** flags are set correctly for the database encoding. A translation may
** take place if the user requests a non-native encoding via ** take place if the user requests a non-native encoding via
** sqlite3_column_data() or sqlite3_column_data16(). If this occurs, then ** sqlite3_column_text() or sqlite3_column_text16(). If this occurs, then
** the MEM_Utf* flags are updated accordingly. ** the MEM_Utf* flags are updated accordingly.
*/ */
#define MEM_Utf8 0x2000 /* String uses UTF-8 encoding */ #define MEM_Utf8 0x2000 /* String uses UTF-8 encoding */

503
src/vdbeapi.c Normal file
View File

@@ -0,0 +1,503 @@
/*
** 2004 May 26
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
/**************************** sqlite3_value_ *******************************
** The following routines extract information from a Mem or sqlite3_value
** structure.
*/
const void *sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
return p->z;
}else{
return sqlite3_value_text(pVal);
}
}
int sqlite3_value_bytes(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( (p->flags & MEM_Blob)!=0 || sqlite3_value_text(pVal) ){
return p->n;
}
return 0;
}
int sqlite3_value_bytes16(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( (p->flags & MEM_Blob)!=0 || sqlite3_value_text16(pVal) ){
return ((Mem *)pVal)->n;
}
return 0;
}
double sqlite3_value_double(sqlite3_value *pVal){
Mem *pMem = (Mem *)pVal;
Realify(pMem, flagsToEnc(pMem->flags));
return pMem->r;
}
int sqlite3_value_int(sqlite3_value *pVal){
Mem *pMem = (Mem *)pVal;
Integerify(pMem, flagsToEnc(pMem->flags));
return (int)pVal->i;
}
long long int sqlite3_value_int64(sqlite3_value *pVal){
Mem *pMem = (Mem *)pVal;
Integerify(pMem, flagsToEnc(pMem->flags));
return pVal->i;
}
const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
if( pVal->flags&MEM_Null ){
/* For a NULL return a NULL Pointer */
return 0;
}
if( pVal->flags&MEM_Str ){
/* If there is already a string representation, make sure it is in
** encoded in UTF-8.
*/
SetEncoding(pVal, MEM_Utf8|MEM_Term);
}else if( !(pVal->flags&MEM_Blob) ){
/* Otherwise, unless this is a blob, convert it to a UTF-8 string */
Stringify(pVal, TEXT_Utf8);
}
return pVal->z;
}
const void *sqlite3_value_text16(sqlite3_value* pVal){
if( pVal->flags&MEM_Null ){
/* For a NULL return a NULL Pointer */
return 0;
}
if( pVal->flags&MEM_Str ){
/* If there is already a string representation, make sure it is in
** encoded in UTF-16 machine byte order.
*/
SetEncoding(pVal, encToFlags(TEXT_Utf16)|MEM_Term);
}else if( !(pVal->flags&MEM_Blob) ){
/* Otherwise, unless this is a blob, convert it to a UTF-16 string */
Stringify(pVal, TEXT_Utf16);
}
return (const void *)(pVal->z);
}
int sqlite3_value_type(sqlite3_value* pVal){
int f = ((Mem *)pVal)->flags;
if( f&MEM_Null ){
return SQLITE3_NULL;
}
if( f&MEM_Int ){
return SQLITE3_INTEGER;
}
if( f&MEM_Real ){
return SQLITE3_FLOAT;
}
if( f&MEM_Str ){
return SQLITE3_TEXT;
}
if( f&MEM_Blob ){
return SQLITE3_BLOB;
}
assert(0);
}
/**************************** sqlite3_result_ *******************************
** The following routines are used by user-defined functions to specify
** the function result.
*/
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_double(sqlite3_context *pCtx, double rVal){
sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
}
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
pCtx->isError = 1;
sqlite3VdbeMemSetStr(&pCtx->s, z, n, TEXT_Utf8, 1);
}
void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
pCtx->isError = 1;
sqlite3VdbeMemSetStr(&pCtx->s, z, n, TEXT_Utf16, 1);
}
void sqlite3_result_int32(sqlite3_context *pCtx, int iVal){
sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
}
void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
}
void sqlite3_result_null(sqlite3_context *pCtx){
sqilte3VdbeMemSetNull(&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_value(sqlite3_context *pCtx, sqlite3_value *pValue){
sqlite3VdbeMemCopy(&pCtx->s, pValue);
}
/*
** Execute the statement pStmt, either until a row of data is ready, the
** statement is completely executed or an error occurs.
*/
int sqlite3_step(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
sqlite *db;
int rc;
if( p->magic!=VDBE_MAGIC_RUN ){
return SQLITE_MISUSE;
}
db = p->db;
if( sqlite3SafetyOn(db) ){
p->rc = SQLITE_MISUSE;
return SQLITE_MISUSE;
}
if( p->explain ){
rc = sqlite3VdbeList(p);
}else{
rc = sqlite3VdbeExec(p);
}
if( sqlite3SafetyOff(db) ){
rc = SQLITE_MISUSE;
}
sqlite3Error(p->db, rc, p->zErrMsg);
return rc;
}
/*
** Return the number of columns in the result set for the statement pStmt.
*/
int sqlite3_column_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
return pVm->nResColumn;
}
/*
** Return the number of values available from the current row of the
** currently executing statement pStmt.
*/
int sqlite3_data_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
if( !pVm->resOnStack ) return 0;
return pVm->nResColumn;
}
/*
** Check to see if column iCol of the given statement is valid. If
** it is, return a pointer to the Mem for the value of that column.
** If iCol is not valid, return a pointer to a Mem which has a value
** of NULL.
*/
static Mem *columnMem(sqlite3_stmt *pStmt, int i){
Vdbe *pVm = (Vdbe *)pStmt;
int vals = sqlite3_data_count(pStmt);
if( i>=vals || i<0 ){
static Mem nullMem;
if( nullMem.flags==0 ){ nullMem.flags = MEM_Null; }
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
return &nullMem;
}
return &pVm->pTos[(1-vals)+i];
}
/**************************** sqlite3_column_ *******************************
** The following routines are used to access elements of the current row
** in the result set.
*/
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
return sqlite3_value_bytes( columnMem(pStmt,i) );
}
int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
return sqlite3_value_bytes16( columnMem(pStmt,i) );
}
double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
return sqlite3_value_double( columnMem(pStmt,i) );
}
int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
return sqlite3_value_int( columnMem(pStmt,i) );
}
long long int sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
return sqlite3_value_int64( columnMem(pStmt,i) );
}
const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
return sqlite3_value_text( columnMem(pStmt,i) );
}
const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
return sqlite3_value_text16( columnMem(pStmt,i) );
}
int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
return sqlite3_value_type( columnMem(pStmt,i) );
}
/*
** Return the name of the Nth column of the result set returned by SQL
** statement pStmt.
*/
const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
Vdbe *p = (Vdbe *)pStmt;
Mem *pColName;
if( N>=sqlite3_column_count(pStmt) || N<0 ){
sqlite3Error(p->db, SQLITE_RANGE, 0);
return 0;
}
pColName = &(p->aColName[N]);
return sqlite3_value_text(pColName);
}
/*
** Return the name of the 'i'th column of the result set of SQL statement
** pStmt, encoded as UTF-16.
*/
const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
Vdbe *p = (Vdbe *)pStmt;
Mem *pColName;
if( N>=sqlite3_column_count(pStmt) || N<0 ){
sqlite3Error(p->db, SQLITE_RANGE, 0);
return 0;
}
pColName = &(p->aColName[N]);
return sqlite3_value_text16(pColName);
}
/*
** This routine returns either the column name, or declaration type (see
** sqlite3_column_decltype16() ) of the 'i'th column of the result set of
** SQL statement pStmt. The returned string is UTF-16 encoded.
**
** The declaration type is returned if 'decltype' is true, otherwise
** the column name.
*/
static const void *columnName16(sqlite3_stmt *pStmt, int i, int decltype){
Vdbe *p = (Vdbe *)pStmt;
if( i>=sqlite3_column_count(pStmt) || i<0 ){
sqlite3Error(p->db, SQLITE_RANGE, 0);
return 0;
}
if( decltype ){
i += p->nResColumn;
}
if( !p->azColName16 ){
p->azColName16 = (void **)sqliteMalloc(sizeof(void *)*p->nResColumn*2);
if( !p->azColName16 ){
sqlite3Error(p->db, SQLITE_NOMEM, 0);
return 0;
}
}
if( !p->azColName16[i] ){
if( SQLITE3_BIGENDIAN ){
p->azColName16[i] = sqlite3utf8to16be(p->azColName[i], -1);
}
if( !p->azColName16[i] ){
sqlite3Error(p->db, SQLITE_NOMEM, 0);
return 0;
}
}
return p->azColName16[i];
}
/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-8.
*/
const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int i){
Vdbe *p = (Vdbe *)pStmt;
if( i>=sqlite3_column_count(pStmt) || i<0 ){
sqlite3Error(p->db, SQLITE_RANGE, 0);
return 0;
}
return p->azColName[i+p->nResColumn];
}
/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-16.
*/
const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int i){
return columnName16(pStmt, i, 1);
}
/******************************* sqlite3_bind_ ***************************
**
** Routines used to attach values to wildcards in a compiled SQL statement.
*/
/*
** Unbind the value bound to variable i in virtual machine p. This is the
** the same as binding a NULL value to the column. If the "i" parameter is
** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
**
** The error code stored in database p->db is overwritten with the return
** value in any case.
*/
static int vdbeUnbind(Vdbe *p, int i){
Mem *pVar;
if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 ){
sqlite3Error(p->db, SQLITE_MISUSE, 0);
return SQLITE_MISUSE;
}
if( i<1 || i>p->nVar ){
sqlite3Error(p->db, SQLITE_RANGE, 0);
return SQLITE_RANGE;
}
i--;
pVar = &p->apVar[i];
if( pVar->flags&MEM_Dyn ){
sqliteFree(pVar->z);
}
pVar->flags = MEM_Null;
sqlite3Error(p->db, SQLITE_OK, 0);
return SQLITE_OK;
}
/*
** Bind a blob value to an SQL statement variable.
*/
int sqlite3_bind_blob(
sqlite3_stmt *p,
int i,
const void *zData,
int nData,
int eCopy
){
Vdbe *p = (Vdbe *)pStmt;
Mem *pVar;
int rc;
rc = vdbeUnbind(p, i);
if( rc ){
return rc;
}
pVar = &p->apVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, 0, eCopy);
return rc;
}
int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
Mem *pVar;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetReal(&p->apVar[i-1], rValue);
}
return SQLITE_OK;
}
int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
return sqlite3_bind_int64(p, i, (long long int)iValue);
}
int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, long long int iValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetInt(&p->apVar[i-1], iValue);
}
return rc;
}
int sqlite3_bind_null(sqlite3_stmt* p, int i){
return vdbeUnbind((Vdbe *)p, i);
}
int sqlite3_bind_text(
sqlite3_stmt *pStmt,
int i,
const char *zData,
int nData,
int eCopy
){
Vdbe *p = (Vdbe *)pStmt;
Mem *pVar;
int rc;
rc = vdbeUnbind(p, i);
if( rc ){
return rc;
}
pVar = &p->apVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, TEXT_Utf8, eCopy);
if( rc ){
return rc;
}
rc = sqlite3VdbeSetEncoding(pVar, p->db->enc);
return rc;
}
int sqlite3_bind_text16(
sqlite3_stmt *pStmt,
int i,
const void *zData,
int nData,
int eCopy
){
Vdbe *p = (Vdbe *)pStmt;
Mem *pVar;
int rc;
rc = vdbeUnbind(p, i);
if( rc ){
return rc;
}
Mem *pVar = &p->apVar[i-1];
/* There may or may not be a byte order mark at the start of the UTF-16.
** Either way set 'txt_enc' to the TEXT_Utf16* value indicating the
** actual byte order used by this string. If the string does happen
** to contain a BOM, then move zData so that it points to the first
** byte after the BOM.
*/
txt_enc = sqlite3UtfReadBom(zData, nData);
if( txt_enc ){
zData = (void *)(((u8 *)zData) + 2);
nData -= 2;
}else{
txt_enc = SQLITE3_BIGENDIAN?TEXT_Utf16be:TEXT_Utf16le;
}
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, txt_enc, eCopy);
if( rc ){
return rc;
}
rc = sqlite3VdbeSetEncoding(pVar, p->db->enc);
return rc;
}

View File

@@ -442,7 +442,7 @@ void *sqlite3_user_data(sqlite3_context *p){
** the internals of the sqlite3_context structure which is only defined in ** the internals of the sqlite3_context structure which is only defined in
** this source file. ** this source file.
*/ */
void *sqlite3_get_context(sqlite3_context *p, int nByte){ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
assert( p && p->pFunc && p->pFunc->xStep ); assert( p && p->pFunc && p->pFunc->xStep );
if( p->pAgg==0 ){ if( p->pAgg==0 ){
if( nByte<=NBFS ){ if( nByte<=NBFS ){
@@ -584,7 +584,7 @@ int sqlite3VdbeList(
/* Even though this opcode does not put dynamic strings onto the /* Even though this opcode does not put dynamic strings onto the
** the stack, they may become dynamic if the user calls ** the stack, they may become dynamic if the user calls
** sqlite3_column_data16(), causing a translation to UTF-16 encoding. ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
*/ */
if( p->pTos==&p->aStack[4] ){ if( p->pTos==&p->aStack[4] ){
for(i=0; i<5; i++){ for(i=0; i<5; i++){

398
src/vdbemem.c Normal file
View File

@@ -0,0 +1,398 @@
/*
** 2004 May 26
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to manipulate "Mem" structure. A "Mem"
** stores a single value in the VDBE. Mem is an opaque structure visible
** only within the VDBE. Interface routines refer to a Mem using the
** name sqlite_value
*/
#include "sqliteInt.h"
#include "os.h"
#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".
**
** 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) */
/* If this is not a string, do nothing. */
if( !(pMem->flags&MEM_Str) ){
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;
}
/* 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);
}
}
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;
}
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 *)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;
}
}
/* 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;
}
return SQLITE_OK;
}
static void releaseMem(Mem *p){
if( p->flags & MEM_Dyn ){
sqliteFree(p);
}
}
/*
** Delete any previous value and set the value stored in *pMem to NULL.
*/
void sqlite3VdbeMemSetNull(Mem *pMem){
releaseMem(pMem);
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){
releaseMem(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){
releaseMem(pMem);
pMem->r = val;
pMem->flags = MEM_Real;
}
/*
** Copy the contents of memory cell pFrom into pTo.
*/
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);
}
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;
releaseMem(pMem);
if( !z ){
/* If z is NULL, just set *pMem to contain NULL. */
return SQLITE_OK;
}
pMem->z = (char *)z;
if( eCopy ){
pMem->flags = MEM_Ephem|MEM_Str;
}else{
pMem->flags = MEM_Static|MEM_Str;
}
pMem->flags |= encToFlags(enc);
pMem->n = n;
switch( enc ){
case 0:
pMem->flags |= MEM_Blob;
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->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->flags |= MEM_Term;
}
break;
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;
}
}
/* 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;
}
/*
** 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;
}