From 51ad0ecd282d94a8ba1eb19e46de198a7bfe3d1e Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Mon, 24 May 2004 12:39:02 +0000 Subject: [PATCH] Non-aggregate SQL functions use sqlite_value* instead of const char * for argument values. (CVS 1449) FossilOrigin-Name: 1e47d7384d5fdfceb6ec737c656f70be59ba5b01 --- manifest | 26 ++++---- manifest.uuid | 2 +- src/date.c | 26 ++++---- src/func.c | 158 ++++++++++++++++++++++++++++-------------------- src/main.c | 4 +- src/sqlite.h.in | 7 +-- src/tclsqlite.c | 10 ++- src/test1.c | 37 +++++++----- src/utf.c | 4 +- src/vdbe.c | 27 ++++----- 10 files changed, 168 insertions(+), 133 deletions(-) diff --git a/manifest b/manifest index b97a7e359d..f969f54ce2 100644 --- a/manifest +++ b/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 diff --git a/manifest.uuid b/manifest.uuid index 6dcb54e50b..4daa42614d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a554bf6c7075839f760a2ff944ac61b32cab0821 \ No newline at end of file +1e47d7384d5fdfceb6ec737c656f70be59ba5b01 \ No newline at end of file diff --git a/src/date.c b/src/date.c index d2d7418eae..21589bd107 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 #include @@ -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; i30 ) 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=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=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; iaFunc, azTypeFuncs[i], n); diff --git a/src/main.c b/src/main.c index 09883aa044..6ca0249516 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 9eeedabc0c..a2d4d0ff55 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 a846ad6bc3..cf60288cff 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; iinterp, Tcl_DStringValue(&cmd)); if( rc ){ diff --git a/src/test1.c b/src/test1.c index 2a208124fc..13f18fbee9 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=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 cb093144eb..6f9dff106c 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 e4d814b86b..664ee60682 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; iflags & 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; }