aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ctime.c3
-rw-r--r--src/func.c78
-rw-r--r--src/sqliteInt.h6
-rw-r--r--src/test_config.c6
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