diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ctime.c | 3 | ||||
-rw-r--r-- | src/func.c | 78 | ||||
-rw-r--r-- | src/sqliteInt.h | 6 | ||||
-rw-r--r-- | src/test_config.c | 6 |
4 files changed, 93 insertions, 0 deletions
diff --git a/src/ctime.c b/src/ctime.c index e3e1e79a9..f0fdccbdc 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -259,6 +259,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_LOCKING_STYLE "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), #endif +#if SQLITE_ENABLE_MATH_FUNCTIONS + "ENABLE_MATH_FUNCTIONS" +#endif #if SQLITE_ENABLE_MEMORY_MANAGEMENT "ENABLE_MEMORY_MANAGEMENT", #endif diff --git a/src/func.c b/src/func.c index 5d00c94a9..09e44345d 100644 --- a/src/func.c +++ b/src/func.c @@ -1904,6 +1904,75 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ return 1; } +/* Extra math functions that require linking with -lm +*/ +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS +/* +** Implementation SQL functions: +** +** ceil(X) +** ceiling(X) +** floor(X) +** +** The sqlite3_user_data() pointer is a pointer to the libm implementation +** of the underlying C function. +*/ +static void ceilingFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_INTEGER: + sqlite3_result_int64(context, sqlite3_value_int64(argv[0])); + break; + case SQLITE_NULL: + break; + default: { + double (*x)(double) = (double(*)(double))sqlite3_user_data(context); + sqlite3_result_double(context, x(sqlite3_value_double(argv[0]))); + break; + } + } +} + +/* +** Implementation of SQL functions: +** +** ln(X) - natural logarithm +** log(X) - log base 10 +** log10(X) - log base 10 +** log(X,Y) - log base Y +*/ +static void logFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double x, y, ans; + assert( argc==1 || argc==2 ); + if( sqlite3_value_type(argv[0])==SQLITE_NULL + || (x = sqlite3_value_double(argv[0]))<0.0 + ){ + return; /* Return NULL for a domain error */ + } + ans = log(x); + if( argc==2 ){ + if( sqlite3_value_type(argv[1])==SQLITE_NULL + || (y = sqlite3_value_double(argv[1]))<0.0 + ){ + return; /* Return NULL for a domain error */ + } + ans /= log(y); + }else if( sqlite3_user_data(context)!=0 ){ + /* Convert from natural logarithm to log base 10 */ + ans *= 0.43429448190325178672; + } + sqlite3_result_double(context, ans); +} +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ + /* ** All of the FuncDef structures in the aBuiltinFunc[] array above ** to the global function hash table. This occurs at start-time (as @@ -2024,6 +2093,15 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(coalesce, 0, 0, 0, 0 ), INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS + MFUNCTION(ceil, 1, ceil, ceilingFunc ), + MFUNCTION(ceiling, 1, ceil, ceilingFunc ), + MFUNCTION(floor, 1, floor, ceilingFunc ), + FUNCTION(ln, 1, 0, 0, logFunc ), + FUNCTION(log, 1, 1, 0, logFunc ), + FUNCTION(log10, 1, 1, 0, logFunc ), + FUNCTION(log, 2, 0, 0, logFunc ), +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ }; #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1efa62142..438f79c09 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1864,6 +1864,9 @@ struct FuncDestructor { ** a single query. The iArg is ignored. The user-data is always set ** to a NULL pointer. The bNC parameter is not used. ** +** MFUNCTION(zName, nArg, xPtr, xFunc) +** For math-library functions. xPtr is an arbitrary pointer. +** ** PURE_DATE(zName, nArg, iArg, bNC, xFunc) ** Used for "pure" date/time functions, this macro is like DFUNCTION ** except that it does set the SQLITE_FUNC_CONSTANT flags. iArg is @@ -1899,6 +1902,9 @@ struct FuncDestructor { #define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define MFUNCTION(zName, nArg, xPtr, xFunc) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ + xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } diff --git a/src/test_config.c b/src/test_config.c index 362e92aa9..8c4fba71d 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -154,6 +154,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS + Tcl_SetVar2(interp, "sqlite_options", "mathlib", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "mathlib", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_ENABLE_MEMSYS3 Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY); #else |