mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Non-aggregate SQL functions use sqlite_value* instead of const char * for
argument values. (CVS 1449) FossilOrigin-Name: 1e47d7384d5fdfceb6ec737c656f70be59ba5b01
This commit is contained in:
26
manifest
26
manifest
@@ -1,5 +1,5 @@
|
||||
C Fix\stypo\sin\svdbe.c\sfrom\sprevious\scommit.\s(CVS\s1448)
|
||||
D 2004-05-24T09:15:39
|
||||
C Non-aggregate\sSQL\sfunctions\suse\ssqlite_value*\sinstead\sof\sconst\schar\s*\sfor\nargument\svalues.\s(CVS\s1449)
|
||||
D 2004-05-24T12:39:02
|
||||
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
|
||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||
@@ -28,15 +28,15 @@ F src/btree.c 51dfa34da5f42762b228d7360cf3273ee403bce8
|
||||
F src/btree.h b65140b5ae891f30d2a39e64b9f0343225553545
|
||||
F src/build.c 35cbeb439b49cca5eb5e8a1de010a5194f4523e8
|
||||
F src/copy.c 4d2038602fd0549d80c59bda27d96f13ea9b5e29
|
||||
F src/date.c fd6a46498449db9c4ff5d45544d9a9b8ba9d8cd5
|
||||
F src/date.c 64fd7169c7d599ec8eaa99121d59e27ddf3d783d
|
||||
F src/delete.c 2e1dda38345416a1ea1c0a6468589a7472334dac
|
||||
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
|
||||
F src/expr.c 5b283e68bd6df365b7c2ad10bd04cc54c2b4b07c
|
||||
F src/func.c 333bbc06cc281f4dbded5dfc4faa1457764bc1b3
|
||||
F src/func.c 3690069d7490b8486f5e54da5c2064b747245730
|
||||
F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
|
||||
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
|
||||
F src/insert.c e510d62d23b4de4d901e7ccbbe7833b7fb3b9570
|
||||
F src/main.c 289e05cf20d74c0b393055745591e6ea8568faee
|
||||
F src/main.c fface1a6e17ef7b3dd4b55089ababc7a91faa4c8
|
||||
F src/md5.c 8e39fdae6d8776b87558e91dcc94740c9b635a9c
|
||||
F src/os.h ab42f4a7c4c716f26b988e759b6e12085a3bfc67
|
||||
F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f
|
||||
@@ -54,11 +54,11 @@ F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
|
||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||
F src/select.c 7d77a8bed7eeac23216d42fc1be006fb4352fcdc
|
||||
F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f
|
||||
F src/sqlite.h.in 73a20794a2f65c7b07e770c6b7adac10c2fb0246
|
||||
F src/sqlite.h.in 258c3a11c9c47cf7302cd4e94c1cac296275bb9b
|
||||
F src/sqliteInt.h e1191166ac9055d6c99c97771d3f35212ef2cff2
|
||||
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
|
||||
F src/tclsqlite.c f241854328ee2b06006efded270d84799159f760
|
||||
F src/test1.c b5f2f9f9d866c8a586b8d47c5999d2cbefaac686
|
||||
F src/tclsqlite.c c8b511645f98051f41b5e0d6c3a99feeed9aeeec
|
||||
F src/test1.c 27a5994f6ce76d62162dac6d1d926deee70c73dd
|
||||
F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
|
||||
F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968
|
||||
F src/test4.c b9947c319a5c023c10c1e953e6610abd571c2283
|
||||
@@ -66,10 +66,10 @@ F src/test5.c 9a1f15133f6955f067c5246e564723b5f23ff221
|
||||
F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
|
||||
F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f
|
||||
F src/update.c 1a5e9182596f3ea8c7a141e308a3d2a7e5689fee
|
||||
F src/utf.c 441c5918ee3777cd8e9611cbb810312ed314737d
|
||||
F src/utf.c 1d38da85bffb928fb0d9f301e7db913a6df486ce
|
||||
F src/util.c 4c0adcbc9ce6678dd046931253e45d623c6d279f
|
||||
F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad
|
||||
F src/vdbe.c f80d8f00766babde444ddfee278532b3637caa7b
|
||||
F src/vdbe.c 92994b28770f07c96c5e4777ce22fb78a853bda8
|
||||
F src/vdbe.h 391d5642a83af686f35c228fcd36cb4456d68f44
|
||||
F src/vdbeInt.h 6c2444a60fc030b275dc0cff407cdaa79d84ce86
|
||||
F src/vdbeaux.c 7f0c4ad22d5e61465d509467e2535293b468373a
|
||||
@@ -202,7 +202,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
|
||||
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
|
||||
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
|
||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||
P 4bf925fcfccb18e66be031f8a234f370d581e9ea
|
||||
R 5cf933e584ede2104c85ca14ff28825c
|
||||
P a554bf6c7075839f760a2ff944ac61b32cab0821
|
||||
R 584e2db8cb6f2477ffc6bd281b266ab4
|
||||
U danielk1977
|
||||
Z 737004ce498e3b3e5dc54e69cd512626
|
||||
Z 579d136717a5636755a59ce43f57b420
|
||||
|
@@ -1 +1 @@
|
||||
a554bf6c7075839f760a2ff944ac61b32cab0821
|
||||
1e47d7384d5fdfceb6ec737c656f70be59ba5b01
|
26
src/date.c
26
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 },
|
||||
|
154
src/func.c
154
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( 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;
|
||||
r = sqlite3AtoF(argv[0], 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);
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
|
@@ -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 ){
|
||||
|
37
src/test1.c
37
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;
|
||||
}
|
||||
|
||||
|
||||
|
25
src/vdbe.c
25
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user