diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/func.c | 92 | ||||
-rw-r--r-- | src/vdbeapi.c | 2 |
2 files changed, 92 insertions, 2 deletions
diff --git a/src/func.c b/src/func.c index e1b2195e8..d13ba437c 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.98 2005/05/24 12:01:02 danielk1977 Exp $ +** $Id: func.c,v 1.99 2005/06/22 10:53:59 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -79,6 +79,93 @@ static void typeofFunc( } /* +** Convert the argument to a numeric type. +*/ +static void numericFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *z = 0; + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_NULL: { + sqlite3_result_int(context, 0); + break; + } + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + sqlite3_result_value(context, argv[0]); + break; + } + case SQLITE_TEXT: + case SQLITE_BLOB: { + z = sqlite3_value_text(argv[0]); + while( *z && *z!='.' ){ z++; } + if( *z ){ + sqlite3_result_double(context, sqlite3_value_double(argv[0])); + }else{ + sqlite3_result_int64(context, sqlite3_value_int64(argv[0])); + } + break; + } + } +} + +/* +** Convert the argument to TEXT +*/ +static void textFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_NULL: { + sqlite3_result_text(context, "", 0, SQLITE_STATIC); + break; + } + case SQLITE_BLOB: + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + sqlite3_result_text(context, sqlite3_value_text(argv[0]), + sqlite3_value_bytes(argv[0]), SQLITE_TRANSIENT); + break; + } + case SQLITE_TEXT: { + sqlite3_result_value(context, argv[0]); + break; + } + } +} + +/* +** Convert the argument to TEXT +*/ +static void blobFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_NULL: { + sqlite3_result_blob(context, "", 0, SQLITE_STATIC); + break; + } + case SQLITE_TEXT: + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + sqlite3_result_blob(context, sqlite3_value_text(argv[0]), + sqlite3_value_bytes(argv[0]), SQLITE_TRANSIENT); + break; + } + case SQLITE_BLOB: { + sqlite3_result_value(context, argv[0]); + break; + } + } +} + +/* ** Implementation of the length() function */ static void lengthFunc( @@ -971,6 +1058,9 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "last_insert_rowid", 0, 1, SQLITE_UTF8, 0, last_insert_rowid }, { "changes", 0, 1, SQLITE_UTF8, 0, changes }, { "total_changes", 0, 1, SQLITE_UTF8, 0, total_changes }, + { "text", 1, 0, SQLITE_UTF8, 0, textFunc }, + { "numeric", 1, 0, SQLITE_UTF8, 0, numericFunc }, + { "blob", 1, 0, SQLITE_UTF8, 0, blobFunc }, #ifdef SQLITE_SOUNDEX { "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc}, #endif diff --git a/src/vdbeapi.c b/src/vdbeapi.c index f07bc8899..99da1c30b 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -84,7 +84,7 @@ void sqlite3_result_blob( int n, void (*xDel)(void *) ){ - assert( n>0 ); + assert( n>=0 ); sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel); } void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ |