diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/date.c | 26 | ||||
-rw-r--r-- | src/func.c | 158 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/sqlite.h.in | 7 | ||||
-rw-r--r-- | src/tclsqlite.c | 10 | ||||
-rw-r--r-- | src/test1.c | 37 | ||||
-rw-r--r-- | src/utf.c | 4 | ||||
-rw-r--r-- | src/vdbe.c | 27 |
8 files changed, 154 insertions, 119 deletions
diff --git a/src/date.c b/src/date.c index d2d7418ea..21589bd10 100644 --- a/src/date.c +++ b/src/date.c @@ -16,7 +16,7 @@ ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: date.c,v 1.20 2004/05/24 07:04:26 danielk1977 Exp $ +** $Id: date.c,v 1.21 2004/05/24 12:39:02 danielk1977 Exp $ ** ** NOTES: ** @@ -641,12 +641,14 @@ static int parseModifier(const char *zMod, DateTime *p){ ** the resulting time into the DateTime structure p. Return 0 ** on success and 1 if there are any errors. */ -static int isDate(int argc, const char **argv, DateTime *p){ +static int isDate(int argc, sqlite3_value **argv, DateTime *p){ int i; if( argc==0 ) return 1; - if( argv[0]==0 || parseDateOrTime(argv[0], p) ) return 1; + if( SQLITE3_NULL==sqlite3_value_type(argv[0]) || + parseDateOrTime(sqlite3_value_data(argv[0]), p) ) return 1; for(i=1; i<argc; i++){ - if( argv[i]==0 || parseModifier(argv[i], p) ) return 1; + if( SQLITE3_NULL==sqlite3_value_type(argv[i]) || + parseModifier(sqlite3_value_data(argv[i]), p) ) return 1; } return 0; } @@ -662,7 +664,7 @@ static int isDate(int argc, const char **argv, DateTime *p){ ** ** Return the julian day number of the date specified in the arguments */ -static void juliandayFunc(sqlite_func *context, int argc, const char **argv){ +static void juliandayFunc(sqlite_func *context, int argc, sqlite3_value **argv){ DateTime x; if( isDate(argc, argv, &x)==0 ){ computeJD(&x); @@ -675,7 +677,7 @@ static void juliandayFunc(sqlite_func *context, int argc, const char **argv){ ** ** Return YYYY-MM-DD HH:MM:SS */ -static void datetimeFunc(sqlite_func *context, int argc, const char **argv){ +static void datetimeFunc(sqlite_func *context, int argc, sqlite3_value **argv){ DateTime x; if( isDate(argc, argv, &x)==0 ){ char zBuf[100]; @@ -691,7 +693,7 @@ static void datetimeFunc(sqlite_func *context, int argc, const char **argv){ ** ** Return HH:MM:SS */ -static void timeFunc(sqlite_func *context, int argc, const char **argv){ +static void timeFunc(sqlite_func *context, int argc, sqlite3_value **argv){ DateTime x; if( isDate(argc, argv, &x)==0 ){ char zBuf[100]; @@ -706,7 +708,7 @@ static void timeFunc(sqlite_func *context, int argc, const char **argv){ ** ** Return YYYY-MM-DD */ -static void dateFunc(sqlite_func *context, int argc, const char **argv){ +static void dateFunc(sqlite_func *context, int argc, sqlite3_value **argv){ DateTime x; if( isDate(argc, argv, &x)==0 ){ char zBuf[100]; @@ -735,13 +737,13 @@ static void dateFunc(sqlite_func *context, int argc, const char **argv){ ** %Y year 0000-9999 ** %% % */ -static void strftimeFunc(sqlite_func *context, int argc, const char **argv){ +static void strftimeFunc(sqlite_func *context, int argc, sqlite3_value **argv){ DateTime x; int n, i, j; char *z; - const char *zFmt = argv[0]; + const char *zFmt = sqlite3_value_data(argv[0]); char zBuf[100]; - if( argv[0]==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++){ if( zFmt[i]=='%' ){ switch( zFmt[i+1] ){ @@ -851,7 +853,7 @@ void sqlite3RegisterDateTimeFunctions(sqlite *db){ char *zName; int nArg; int dataType; - void (*xFunc)(sqlite_func*,int,const char**); + void (*xFunc)(sqlite_func*,int,sqlite3_value**); } aFuncs[] = { #ifndef SQLITE_OMIT_DATETIME_FUNCS { "julianday", -1, SQLITE_NUMERIC, juliandayFunc }, diff --git a/src/func.c b/src/func.c index 4e8606717..ea30997a3 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.49 2004/05/24 07:04:26 danielk1977 Exp $ +** $Id: func.c,v 1.50 2004/05/24 12:39:02 danielk1977 Exp $ */ #include <ctype.h> #include <math.h> @@ -28,25 +28,28 @@ /* ** Implementation of the non-aggregate min() and max() functions */ -static void minmaxFunc(sqlite_func *context, int argc, const char **argv){ +static void minmaxFunc(sqlite_func *context, int argc, sqlite3_value **argv){ const char *zBest; int i; int (*xCompare)(const char*, const char*); int mask; /* 0 for min() or 0xffffffff for max() */ + const char *zArg; if( argc==0 ) return; mask = (int)sqlite3_user_data(context); - zBest = argv[0]; + zBest = sqlite3_value_data(argv[0]); if( zBest==0 ) return; - if( argv[1][0]=='n' ){ + zArg = sqlite3_value_data(argv[1]); + if( zArg[0]=='n' ){ xCompare = sqlite3Compare; }else{ xCompare = strcmp; } for(i=2; i<argc; i+=2){ - if( argv[i]==0 ) return; - if( (xCompare(argv[i], zBest)^mask)<0 ){ - zBest = argv[i]; + zArg = sqlite3_value_data(argv[i]); + if( zArg==0 ) return; + if( (xCompare(zArg, zBest)^mask)<0 ){ + zBest = zArg; } } sqlite3_set_result_string(context, zBest, -1); @@ -55,20 +58,20 @@ static void minmaxFunc(sqlite_func *context, int argc, const char **argv){ /* ** Return the type of the argument. */ -static void typeofFunc(sqlite_func *context, int argc, const char **argv){ +static void typeofFunc(sqlite_func *context, int argc, sqlite3_value **argv){ assert( argc==2 ); - sqlite3_set_result_string(context, argv[1], -1); + sqlite3_set_result_string(context, sqlite3_value_data(argv[1]), -1); } /* ** Implementation of the length() function */ -static void lengthFunc(sqlite_func *context, int argc, const char **argv){ +static void lengthFunc(sqlite_func *context, int argc, sqlite3_value **argv){ const char *z; int len; assert( argc==1 ); - z = argv[0]; + z = sqlite3_value_data(argv[0]); if( z==0 ) return; #ifdef SQLITE_UTF8 for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; } @@ -81,10 +84,10 @@ static void lengthFunc(sqlite_func *context, int argc, const char **argv){ /* ** Implementation of the abs() function */ -static void absFunc(sqlite_func *context, int argc, const char **argv){ +static void absFunc(sqlite_func *context, int argc, sqlite3_value **argv){ const char *z; assert( argc==1 ); - z = argv[0]; + z = sqlite3_value_data(argv[0]); if( z==0 ) return; if( z[0]=='-' && isdigit(z[1]) ) z++; sqlite3_set_result_string(context, z, -1); @@ -93,7 +96,7 @@ static void absFunc(sqlite_func *context, int argc, const char **argv){ /* ** Implementation of the substr() function */ -static void substrFunc(sqlite_func *context, int argc, const char **argv){ +static void substrFunc(sqlite_func *context, int argc, sqlite3_value **argv){ const char *z; #ifdef SQLITE_UTF8 const char *z2; @@ -101,10 +104,10 @@ static void substrFunc(sqlite_func *context, int argc, const char **argv){ #endif int p1, p2, len; assert( argc==3 ); - z = argv[0]; + z = sqlite3_value_data(argv[0]); if( z==0 ) return; - p1 = atoi(argv[1]?argv[1]:0); - p2 = atoi(argv[2]?argv[2]:0); + p1 = sqlite3_value_int(argv[1]); + p2 = sqlite3_value_int(argv[2]); #ifdef SQLITE_UTF8 for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z2)!=0x80 ) len++; } #else @@ -139,16 +142,19 @@ static void substrFunc(sqlite_func *context, int argc, const char **argv){ /* ** Implementation of the round() function */ -static void roundFunc(sqlite_func *context, int argc, const char **argv){ - int n; +static void roundFunc(sqlite_func *context, int argc, sqlite3_value **argv){ + int n = 0; double r; char zBuf[100]; assert( argc==1 || argc==2 ); - if( argv[0]==0 || (argc==2 && argv[1]==0) ) return; - n = argc==2 ? atoi(argv[1]) : 0; - if( n>30 ) n = 30; - if( n<0 ) n = 0; - r = sqlite3AtoF(argv[0], 0); + if( argc==2 ){ + if( SQLITE3_NULL==sqlite3_value_type(argv[1]) ) return; + n = sqlite3_value_int(argv[1]); + if( n>30 ) n = 30; + if( n<0 ) n = 0; + } + 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); } @@ -156,21 +162,21 @@ static void roundFunc(sqlite_func *context, int argc, const char **argv){ /* ** Implementation of the upper() and lower() SQL functions. */ -static void upperFunc(sqlite_func *context, int argc, const char **argv){ +static void upperFunc(sqlite_func *context, int argc, sqlite3_value **argv){ char *z; int i; - if( argc<1 || argv[0]==0 ) return; - z = sqlite3_set_result_string(context, argv[0], -1); + if( argc<1 ) return; + z = sqlite3_set_result_string(context, sqlite3_value_data(argv[0]), -1); if( z==0 ) return; for(i=0; z[i]; i++){ if( islower(z[i]) ) z[i] = toupper(z[i]); } } -static void lowerFunc(sqlite_func *context, int argc, const char **argv){ +static void lowerFunc(sqlite_func *context, int argc, sqlite3_value **argv){ char *z; int i; - if( argc<1 || argv[0]==0 ) return; - z = sqlite3_set_result_string(context, argv[0], -1); + if( argc<1 ) return; + z = sqlite3_set_result_string(context, sqlite3_value_data(argv[0]), -1); if( z==0 ) return; for(i=0; z[i]; i++){ if( isupper(z[i]) ) z[i] = tolower(z[i]); @@ -182,11 +188,11 @@ static void lowerFunc(sqlite_func *context, int argc, const char **argv){ ** All three do the same thing. They return the first non-NULL ** argument. */ -static void ifnullFunc(sqlite_func *context, int argc, const char **argv){ +static void ifnullFunc(sqlite_func *context, int argc, sqlite3_value **argv){ int i; for(i=0; i<argc; i++){ - if( argv[i] ){ - sqlite3_set_result_string(context, argv[i], -1); + if( SQLITE3_NULL!=sqlite3_value_type(argv[i]) ){ + sqlite3_set_result_string(context, sqlite3_value_data(argv[i]), -1); break; } } @@ -195,7 +201,7 @@ static void ifnullFunc(sqlite_func *context, int argc, const char **argv){ /* ** Implementation of random(). Return a random integer. */ -static void randomFunc(sqlite_func *context, int argc, const char **argv){ +static void randomFunc(sqlite_func *context, int argc, sqlite3_value **argv){ int r; sqlite3Randomness(sizeof(r), &r); sqlite3_set_result_int(context, r); @@ -205,7 +211,11 @@ static void randomFunc(sqlite_func *context, int argc, const char **argv){ ** Implementation of the last_insert_rowid() SQL function. The return ** value is the same as the sqlite3_last_insert_rowid() API function. */ -static void last_insert_rowid(sqlite_func *context, int arg, const char **argv){ +static void last_insert_rowid( + sqlite_func *context, + int arg, + sqlite3_value **argv +){ sqlite *db = sqlite3_user_data(context); sqlite3_set_result_int(context, sqlite3_last_insert_rowid(db)); } @@ -214,17 +224,21 @@ static void last_insert_rowid(sqlite_func *context, int arg, const char **argv){ ** Implementation of the change_count() SQL function. The return ** value is the same as the sqlite3_changes() API function. */ -static void change_count(sqlite_func *context, int arg, const char **argv){ +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)); } /* ** Implementation of the last_statement_change_count() SQL function. The -** return value is the same as the sqlite3_last_statement_changes() API function. +** return value is the same as the sqlite3_last_statement_changes() API +** function. */ -static void last_statement_change_count(sqlite_func *context, int arg, - const char **argv){ +static void last_statement_change_count( + sqlite_func *context, + int arg, + sqlite3_value **argv +){ sqlite *db = sqlite3_user_data(context); sqlite3_set_result_int(context, sqlite3_last_statement_changes(db)); } @@ -238,11 +252,16 @@ static void last_statement_change_count(sqlite_func *context, int arg, ** ** is implemented as like(A,B). */ -static void likeFunc(sqlite_func *context, int arg, const char **argv){ - if( argv[0]==0 || argv[1]==0 ) return; - sqlite3_set_result_int(context, - sqlite3LikeCompare((const unsigned char*)argv[0], - (const unsigned char*)argv[1])); +static void likeFunc( + sqlite_func *context, + int argc, + 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, sqlite3LikeCompare(zA, zB)); + } } /* @@ -254,11 +273,12 @@ static void likeFunc(sqlite_func *context, int arg, const char **argv){ ** ** is implemented as glob(A,B). */ -static void globFunc(sqlite_func *context, int arg, const char **argv){ - if( argv[0]==0 || argv[1]==0 ) return; - sqlite3_set_result_int(context, - sqlite3GlobCompare((const unsigned char*)argv[0], - (const unsigned char*)argv[1])); +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)); + } } /* @@ -266,9 +286,11 @@ static void globFunc(sqlite_func *context, int arg, const char **argv){ ** argument if the arguments are different. The result is NULL if the ** arguments are equal to each other. */ -static void nullifFunc(sqlite_func *context, int argc, const char **argv){ - if( argv[0]!=0 && sqlite3Compare(argv[0],argv[1])!=0 ){ - sqlite3_set_result_string(context, argv[0], -1); +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); } } @@ -276,7 +298,7 @@ static void nullifFunc(sqlite_func *context, int argc, const char **argv){ ** Implementation of the VERSION(*) function. The result is the version ** of the SQLite library that is running. */ -static void versionFunc(sqlite_func *context, int argc, const char **argv){ +static void versionFunc(sqlite_func *context, int argc, sqlite3_value **argv){ sqlite3_set_result_string(context, sqlite3_version, -1); } @@ -291,22 +313,23 @@ static void versionFunc(sqlite_func *context, int argc, const char **argv){ ** "NULL". Otherwise, the argument is enclosed in single quotes with ** single-quote escapes. */ -static void quoteFunc(sqlite_func *context, int argc, const char **argv){ +static void quoteFunc(sqlite_func *context, int argc, sqlite3_value **argv){ + const char *zArg = sqlite3_value_data(argv[0]); if( argc<1 ) return; - if( argv[0]==0 ){ + if( zArg==0 ){ sqlite3_set_result_string(context, "NULL", 4); - }else if( sqlite3IsNumber(argv[0], 0, TEXT_Utf8) ){ - sqlite3_set_result_string(context, argv[0], -1); + }else if( sqlite3IsNumber(zArg, 0, TEXT_Utf8) ){ + sqlite3_set_result_string(context, zArg, -1); }else{ int i,j,n; char *z; - for(i=n=0; argv[0][i]; i++){ if( argv[0][i]=='\'' ) n++; } + for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } z = sqliteMalloc( i+n+3 ); if( z==0 ) return; z[0] = '\''; - for(i=0, j=1; argv[0][i]; i++){ - z[j++] = argv[0][i]; - if( argv[0][i]=='\'' ){ + for(i=0, j=1; zArg[i]; i++){ + z[j++] = zArg[i]; + if( zArg[i]=='\'' ){ z[j++] = '\''; } } @@ -321,7 +344,7 @@ static void quoteFunc(sqlite_func *context, int argc, const char **argv){ /* ** Compute the soundex encoding of a word. */ -static void soundexFunc(sqlite_func *context, int argc, const char **argv){ +static void soundexFunc(sqlite_func *context, int argc, sqlite3_value **argv){ char zResult[8]; const char *zIn; int i, j; @@ -336,7 +359,7 @@ static void soundexFunc(sqlite_func *context, int argc, const char **argv){ 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, }; assert( argc==1 ); - zIn = argv[0]; + zIn = sqlite3_value_data(argv[0]); for(i=0; zIn[i] && !isalpha(zIn[i]); i++){} if( zIn[i] ){ zResult[0] = toupper(zIn[i]); @@ -362,7 +385,7 @@ static void soundexFunc(sqlite_func *context, int argc, const char **argv){ ** This function generates a string of random characters. Used for ** generating test data. */ -static void randStr(sqlite_func *context, int argc, const char **argv){ +static void randStr(sqlite_func *context, int argc, sqlite3_value **argv){ static const unsigned char zSrc[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -371,14 +394,14 @@ static void randStr(sqlite_func *context, int argc, const char **argv){ int iMin, iMax, n, r, i; unsigned char zBuf[1000]; if( argc>=1 ){ - iMin = atoi(argv[0]); + iMin = atoi(sqlite3_value_data(argv[0])); if( iMin<0 ) iMin = 0; if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1; }else{ iMin = 1; } if( argc>=2 ){ - iMax = atoi(argv[1]); + iMax = atoi(sqlite3_value_data(argv[1])); if( iMax<iMin ) iMax = iMin; if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1; }else{ @@ -564,7 +587,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite *db){ signed char nArg; signed char dataType; u8 argType; /* 0: none. 1: db 2: (-1) */ - void (*xFunc)(sqlite_func*,int,const char**); + void (*xFunc)(sqlite_func*,int,sqlite3_value **); } aFuncs[] = { { "min", -1, SQLITE_ARGS, 0, minmaxFunc }, { "min", 0, 0, 0, 0 }, @@ -635,6 +658,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite *db){ aAggs[i].nArg, aAggs[i].xStep, aAggs[i].xFinalize, pArg); sqlite3_function_type(db, aAggs[i].zName, aAggs[i].dataType); } + for(i=0; i<sizeof(azTypeFuncs)/sizeof(azTypeFuncs[0]); i++){ int n = strlen(azTypeFuncs[i]); FuncDef *p = sqlite3HashFind(&db->aFunc, azTypeFuncs[i], n); diff --git a/src/main.c b/src/main.c index 09883aa04..6ca024951 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.185 2004/05/22 17:41:59 drh Exp $ +** $Id: main.c,v 1.186 2004/05/24 12:39:02 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -861,7 +861,7 @@ int sqlite3_create_function( sqlite *db, /* Add the function to this database connection */ const char *zName, /* Name of the function to add */ int nArg, /* Number of arguments */ - void (*xFunc)(sqlite_func*,int,const char**), /* The implementation */ + void (*xFunc)(sqlite_func*,int,sqlite3_value **), /* The implementation */ void *pUserData /* User data */ ){ FuncDef *p; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9eeedabc0..a2d4d0ff5 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.72 2004/05/24 09:10:11 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.73 2004/05/24 12:39:02 danielk1977 Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ @@ -422,6 +422,7 @@ const char *sqlite3_libencoding(void); ** the implementations of user-defined functions. */ typedef struct sqlite_func sqlite_func; +typedef struct Mem sqlite3_value; /* ** Use the following routines to create new user-defined functions. See @@ -431,7 +432,7 @@ int sqlite3_create_function( sqlite*, /* Database where the new function is registered */ const char *zName, /* Name of the new function */ int nArg, /* Number of arguments. -1 means any number */ - void (*xFunc)(sqlite_func*,int,const char**), /* C code to implement */ + void (*xFunc)(sqlite_func*,int,sqlite3_value **), /* C code to implement */ void *pUserData /* Available via the sqlite3_user_data() call */ ); int sqlite3_create_aggregate( @@ -1340,8 +1341,6 @@ long long int sqlite3_column_int(sqlite3_stmt*,int); */ double sqlite3_column_float(sqlite3_stmt*,int); -typedef struct Mem sqlite3_value; - /* ** Return the type of the sqlite3_value* passed as the first argument. ** The type is one of SQLITE3_NULL, SQLITE3_INTEGER, SQLITE3_FLOAT, diff --git a/src/tclsqlite.c b/src/tclsqlite.c index a846ad6bc..cf60288cf 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -11,7 +11,7 @@ ************************************************************************* ** A TCL Interface to SQLite ** -** $Id: tclsqlite.c,v 1.66 2004/05/22 09:21:21 danielk1977 Exp $ +** $Id: tclsqlite.c,v 1.67 2004/05/24 12:39:02 danielk1977 Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ @@ -379,7 +379,7 @@ static int DbCommitHandler(void *cd){ ** This routine is called to evaluate an SQL function implemented ** using TCL script. */ -static void tclSqlFunc(sqlite_func *context, int argc, const char **argv){ +static void tclSqlFunc(sqlite_func *context, int argc, sqlite3_value **argv){ SqlFunc *p = sqlite3_user_data(context); Tcl_DString cmd; int i; @@ -388,7 +388,11 @@ static void tclSqlFunc(sqlite_func *context, int argc, const char **argv){ Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, p->zScript, -1); for(i=0; i<argc; i++){ - Tcl_DStringAppendElement(&cmd, argv[i] ? argv[i] : ""); + if( SQLITE3_NULL==sqlite3_value_type(argv[i]) ){ + Tcl_DStringAppendElement(&cmd, ""); + }else{ + Tcl_DStringAppendElement(&cmd, sqlite3_value_data(argv[i])); + } } rc = Tcl_Eval(p->interp, Tcl_DStringValue(&cmd)); if( rc ){ diff --git a/src/test1.c b/src/test1.c index 2a208124f..13f18fbee 100644 --- a/src/test1.c +++ b/src/test1.c @@ -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.47 2004/05/22 10:33:04 danielk1977 Exp $ +** $Id: test1.c,v 1.48 2004/05/24 12:39:02 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -307,11 +307,11 @@ static int sqlite_test_close( ** Implementation of the x_coalesce() function. ** Return the first argument non-NULL argument. */ -static void ifnullFunc(sqlite_func *context, int argc, const char **argv){ +static void ifnullFunc(sqlite_func *context, int argc, sqlite3_value **argv){ int i; for(i=0; i<argc; i++){ - if( argv[i] ){ - sqlite3_set_result_string(context, argv[i], -1); + if( SQLITE3_NULL!=sqlite3_value_type(argv[i]) ){ + sqlite3_set_result_string(context, sqlite3_value_data(argv[i]), -1); break; } } @@ -376,10 +376,15 @@ static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){ ** This routine simulates the effect of having two threads attempt to ** use the same database at the same time. */ -static void sqlite3ExecFunc(sqlite_func *context, int argc, const char **argv){ +static void sqlite3ExecFunc( + sqlite_func *context, + int argc, + sqlite3_value **argv +){ struct dstr x; memset(&x, 0, sizeof(x)); - sqlite3_exec((sqlite*)sqlite3_user_data(context), argv[0], + sqlite3_exec((sqlite*)sqlite3_user_data(context), + sqlite3_value_data(argv[0]), execFuncCallback, &x, 0); sqlite3_set_result_string(context, x.z, x.nUsed); sqliteFree(x.z); @@ -648,20 +653,22 @@ static int sqlite_abort( ** The following routine is a user-defined SQL function whose purpose ** is to test the sqlite_set_result() API. */ -static void testFunc(sqlite_func *context, int argc, const char **argv){ +static void testFunc(sqlite_func *context, int argc, sqlite3_value **argv){ while( argc>=2 ){ - if( argv[0]==0 ){ + 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 " "may not be NULL", -1); - }else if( sqlite3StrICmp(argv[0],"string")==0 ){ - sqlite3_set_result_string(context, argv[1], -1); - }else if( argv[1]==0 ){ + }else if( sqlite3StrICmp(zArg0,"string")==0 ){ + sqlite3_set_result_string(context, zArg1, -1); + }else if( zArg1==0 ){ sqlite3_set_result_error(context, "2nd argument may not be NULL if the " "first argument is not \"string\"", -1); - }else if( sqlite3StrICmp(argv[0],"int")==0 ){ - sqlite3_set_result_int(context, atoi(argv[1])); - }else if( sqlite3StrICmp(argv[0],"double")==0 ){ - sqlite3_set_result_double(context, sqlite3AtoF(argv[1], 0)); + }else if( sqlite3StrICmp(zArg0,"int")==0 ){ + sqlite3_set_result_int(context, atoi(zArg1)); + }else if( sqlite3StrICmp(zArg0,"double")==0 ){ + sqlite3_set_result_double(context, sqlite3AtoF(zArg1, 0)); }else{ sqlite3_set_result_error(context,"first argument should be one of: " "string int double", -1); @@ -12,7 +12,7 @@ ** This file contains routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** -** $Id: utf.c,v 1.9 2004/05/23 13:30:58 danielk1977 Exp $ +** $Id: utf.c,v 1.10 2004/05/24 12:39:02 danielk1977 Exp $ ** ** Notes on UTF-8: ** @@ -608,3 +608,5 @@ int sqlite3utfTranslate( } return SQLITE_OK; } + + diff --git a/src/vdbe.c b/src/vdbe.c index e4d814b86..664ee6068 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -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.325 2004/05/24 09:15:39 danielk1977 Exp $ +** $Id: vdbe.c,v 1.326 2004/05/24 12:39:02 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -2269,33 +2269,29 @@ divide_by_zero: ** See also: AggFunc */ case OP_Function: { - int n, i; + int i; Mem *pArg; - char **azArgv; sqlite_func ctx; + sqlite3_value **apVal; + int n = pOp->p1; n = pOp->p1; + apVal = sqliteMalloc(sizeof(sqlite3_value*)*n); + assert( apVal || n==0 ); + pArg = &pTos[1-n]; - azArgv = p->zArgv; for(i=0; i<n; i++, pArg++){ - if( pArg->flags & MEM_Null ){ - azArgv[i] = 0; - }else if( !(pArg->flags&MEM_Str) ){ - Stringify(pArg, TEXT_Utf8); - azArgv[i] = pArg->z; - }else{ - SetEncodingFlags(pArg, db->enc); - SetEncoding(pArg, MEM_Utf8|MEM_Term); - azArgv[i] = pArg->z; - } + SetEncodingFlags(pArg, db->enc); + apVal[i] = pArg; } + ctx.pFunc = (FuncDef*)pOp->p3; ctx.s.flags = MEM_Null; ctx.s.z = 0; ctx.isError = 0; ctx.isStep = 0; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - (*ctx.pFunc->xFunc)(&ctx, n, (const char**)azArgv); + (*ctx.pFunc->xFunc)(&ctx, n, apVal); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; popStack(&pTos, n); pTos++; @@ -2317,6 +2313,7 @@ case OP_Function: { SetEncoding(pTos, encToFlags(db->enc)|MEM_Term); } + if( apVal ) sqliteFree(apVal); break; } |