aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/date.c26
-rw-r--r--src/func.c158
-rw-r--r--src/main.c4
-rw-r--r--src/sqlite.h.in7
-rw-r--r--src/tclsqlite.c10
-rw-r--r--src/test1.c37
-rw-r--r--src/utf.c4
-rw-r--r--src/vdbe.c27
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);
diff --git a/src/utf.c b/src/utf.c
index cb093144e..6f9dff106 100644
--- a/src/utf.c
+++ b/src/utf.c
@@ -12,7 +12,7 @@
** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
-** $Id: utf.c,v 1.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;
}