The R Project SVN R-packages

Rev

Rev 3308 | Rev 3358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3255 mrmanese 1
#include "sqlite_dataframe.h"
3307 mrmanese 2
#include <math.h>
3
#include "Rmath.h"
3255 mrmanese 4
 
5
SEXP sdf_get_variable(SEXP sdf, SEXP name) {
6
    if (!IS_CHARACTER(name)) {
7
        Rprintf("ERROR: argument is not a string.\n");
8
        return R_NilValue;
9
    }
10
 
11
    char *iname = SDF_INAME(sdf);
12
    char *varname = CHAR_ELT(name, 0);
13
 
3324 mrmanese 14
    if (!USE_SDF(iname, TRUE)) return R_NilValue;
3308 mrmanese 15
 
3255 mrmanese 16
    /* check if sdf & varname w/in that sdf exists */
17
    sqlite3_stmt *stmt;
18
    sprintf(g_sql_buf[0], "select [%s] from [%s].sdf_data", varname, iname);
19
 
20
    int res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
21
 
3281 mrmanese 22
    if (_sqlite_error(res)) return R_NilValue;
3255 mrmanese 23
 
24
    const char *coltype = sqlite3_column_decltype(stmt, 0);
25
    sqlite3_finalize(stmt);
26
 
27
 
3281 mrmanese 28
    SEXP ret, value, class = R_NilValue; int nprotected = 0;
3255 mrmanese 29
    PROTECT(ret = NEW_LIST(2)); nprotected++;
30
 
31
    /* set list names */
32
    PROTECT(value = NEW_CHARACTER(2)); nprotected++;
33
    SET_STRING_ELT(value, 0, mkChar("iname"));
34
    SET_STRING_ELT(value, 1, mkChar("varname"));
35
    SET_NAMES(ret, value);
36
 
37
    /* set list values */
38
    SET_VECTOR_ELT(ret, 0, mkString(iname));
39
    SET_VECTOR_ELT(ret, 1, mkString(varname));
40
 
41
    /* set class */
42
    int type = -1;
43
    if (strcmp(coltype, "text") == 0) class = mkChar("character");
44
    else if (strcmp(coltype, "double") == 0) class = mkChar("numeric");
45
    else if (strcmp(coltype, "bit") == 0) class = mkChar("logical");
46
    else if (strcmp(coltype, "integer") == 0 || strcmp(coltype, "int") == 0) {
47
        /* determine if int, factor or ordered */
48
        type = _get_factor_levels1(iname, varname, ret);
49
        switch(type) {
3307 mrmanese 50
            case VAR_INTEGER: class = mkChar("integer"); break;
3255 mrmanese 51
            case VAR_FACTOR: class = mkChar("factor"); break;
52
            case VAR_ORDERED: class = mkChar("ordered");
53
        }
54
 
55
    }
56
 
57
    if (type != VAR_ORDERED) {
58
        PROTECT(value = NEW_CHARACTER(2)); nprotected++;
59
        SET_STRING_ELT(value, 0, mkChar("sqlite.vector"));
60
        SET_STRING_ELT(value, 1, class);
61
    } else {
62
        PROTECT(value = NEW_CHARACTER(3)); nprotected++;
63
        SET_STRING_ELT(value, 0, mkChar("sqlite.vector"));
64
        SET_STRING_ELT(value, 1, class);
65
        SET_STRING_ELT(value, 2, mkChar("factor"));
66
    }
67
    SET_CLASS(ret, value);
68
 
69
    UNPROTECT(nprotected);
70
    return ret;
71
 
72
}
73
 
74
int _get_vector_index_typed_result(sqlite3_stmt *stmt, SEXP *ret, int idx_or_len) {
75
    int added = 1;
76
    if (*ret == NULL || *ret == R_NilValue) {
77
        const char *coltype = sqlite3_column_decltype(stmt, 0);
78
        if (sqlite3_column_type(stmt, 0) == SQLITE_NULL) {
79
            added = 0;
80
        }
81
 
82
        if (strcmp(coltype, "text") == 0) {
83
            PROTECT(*ret = NEW_CHARACTER(idx_or_len));
84
            if (added) 
3284 mrmanese 85
                SET_STRING_ELT(*ret, 0, mkChar((char *)sqlite3_column_text(stmt, 0)));
3255 mrmanese 86
        } else if (strcmp(coltype, "double") == 0) {
87
            PROTECT(*ret = NEW_NUMERIC(idx_or_len));
88
            if (added) REAL(*ret)[0] = sqlite3_column_double(stmt, 0);
89
        } else if (strcmp(coltype, "bit") == 0) {
90
            PROTECT(*ret = NEW_LOGICAL(idx_or_len));
91
            if (added) INTEGER(*ret)[0] = sqlite3_column_int(stmt, 0);
92
        } else if (strcmp(coltype, "integer") == 0 || 
93
                   strcmp(coltype, "int") == 0) {
94
            /* caller should just copy off the vars level attr for factors */
95
            PROTECT(*ret = NEW_INTEGER(idx_or_len));
96
            if (added) INTEGER(*ret)[0] = sqlite3_column_int(stmt, 0);
97
        } else added = 0;
98
 
99
        UNPROTECT(1);
100
    } else {
101
        const char *coltype = sqlite3_column_decltype(stmt, 0);
102
        if (sqlite3_column_type(stmt, 0) == SQLITE_NULL) {
103
            added = 0;
104
        } else if (strcmp(coltype, "text") == 0) {
105
            SET_STRING_ELT(*ret, idx_or_len, 
3284 mrmanese 106
                    mkChar((char *)sqlite3_column_text(stmt, 0)));
3255 mrmanese 107
        } else if (strcmp(coltype, "double") == 0) {
108
            REAL(*ret)[idx_or_len] = sqlite3_column_double(stmt, 0);
109
        } else if (strcmp(coltype, "bit") == 0) {
110
            INTEGER(*ret)[idx_or_len] = sqlite3_column_int(stmt, 0);
111
        } else if (strcmp(coltype, "integer") == 0 ||
112
                   strcmp(coltype, "int") == 0) {
113
            /* caller should just copy off the vars level attr for factors */
114
            INTEGER(*ret)[idx_or_len] = sqlite3_column_int(stmt, 0);
115
        } else added = 0;
116
    }
117
 
118
    return added;
119
}
120
 
121
SEXP sdf_get_variable_length(SEXP svec) {
122
    char *iname = SDF_INAME(svec);
3324 mrmanese 123
    if (!USE_SDF(iname, TRUE)) return R_NilValue;
3255 mrmanese 124
    sprintf(g_sql_buf[0], "[%s].sdf_data", iname);
125
 
126
    SEXP ret;
127
    PROTECT(ret = NEW_INTEGER(1));
128
    INTEGER(ret)[0] = _get_row_count2(g_sql_buf[0]);
129
    UNPROTECT(1);
130
    return ret;
131
}
132
 
133
 
134
SEXP sdf_get_variable_index(SEXP svec, SEXP idx) {
135
    SEXP ret = R_NilValue, tmp;
136
    char *iname = SDF_INAME(svec), *varname = SVEC_VARNAME(svec);
3282 mrmanese 137
    int index, idxlen, i, retlen=0, res;
3255 mrmanese 138
 
3324 mrmanese 139
    if (!USE_SDF(iname, TRUE)) return R_NilValue;
3308 mrmanese 140
 
3255 mrmanese 141
    /* check if sdf exists */
142
    sqlite3_stmt *stmt;
143
    sprintf(g_sql_buf[0], "select [%s] from [%s].sdf_data", varname, iname);
144
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
145
    sqlite3_finalize(stmt);
146
    if (_sqlite_error(res)) { return ret; }
147
 
148
    idxlen = LENGTH(idx);
149
    if (idxlen < 1) return ret;
150
 
151
    sprintf(g_sql_buf[0], "select [%s] from [%s].sdf_data limit ?,1",
152
            varname, iname);
153
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
154
 
155
    /* get data based on index */
156
    if (IS_NUMERIC(idx)) {
157
        index = ((int) REAL(idx)[0]) - 1;
158
        if (index < 0 && idxlen == 1) return ret;
159
 
3281 mrmanese 160
        if (index >= 0) {
3255 mrmanese 161
            sqlite3_bind_int(stmt, 1, index);
162
            res = sqlite3_step(stmt);
163
            if (res == SQLITE_ROW) { 
164
                retlen = _get_vector_index_typed_result(stmt, &ret, idxlen);
165
            } 
166
        } 
167
 
3281 mrmanese 168
        if (index < 0 || res != SQLITE_ROW) {
3255 mrmanese 169
            /* something wrong w/ 1st idx, and it is quietly ignored. we make 
170
             * a "dummy" call to setup the SEXP */
171
            sqlite3_bind_int(stmt, 1, 0);
172
            _get_vector_index_typed_result(stmt, &ret, idxlen - 1);
173
            retlen = 0;
174
        }
175
 
176
        if (idxlen > 1) {
177
            for (i = 1; i < idxlen; i++) {
178
                index = ((int) REAL(idx)[i]) - 1;
179
                if (index < 0) continue;
180
                sqlite3_reset(stmt);
181
                sqlite3_bind_int(stmt, 1, index);
182
                res = sqlite3_step(stmt);
183
                if (res == SQLITE_ROW)
184
                    retlen += _get_vector_index_typed_result(stmt, &ret, retlen); 
185
            }
186
        }
187
    } else if (IS_INTEGER(idx)) {
188
        /* similar to REAL (IS_NUMERIC) above, except that we don't have
189
         * to cast idx to int. can't refactor this out, sucks. */
190
        index = INTEGER(idx)[0] - 1;
191
        if (index < 0 && idxlen == 1) return ret;
192
 
3281 mrmanese 193
        if (index >= 0) {
3255 mrmanese 194
            sqlite3_bind_int(stmt, 1, index);
3281 mrmanese 195
            res = sqlite3_step(stmt);
196
            if (res == SQLITE_ROW) { 
197
                retlen = _get_vector_index_typed_result(stmt, &ret, idxlen);
198
            } 
199
        } 
200
 
201
        if (index < 0 || res != SQLITE_ROW) {
202
            /* something wrong w/ 1st idx, and it is quietly ignored. we make 
203
             * a "dummy" call to setup the SEXP */
3255 mrmanese 204
            sqlite3_bind_int(stmt, 1, 0);
205
            _get_vector_index_typed_result(stmt, &ret, idxlen - 1);
206
            retlen = 0;
207
        }
208
 
209
        if (idxlen > 1) {
210
            for (i = 1; i < idxlen; i++) {
211
                index = INTEGER(idx)[i] - 1;
212
                if (index < 0) continue;
213
                sqlite3_reset(stmt);
214
                sqlite3_bind_int(stmt, 1, index);
215
                sqlite3_step(stmt);
216
                retlen += _get_vector_index_typed_result(stmt, &ret, retlen); 
217
            }
218
        }
219
 
220
    } else if (IS_LOGICAL(idx)) {
221
        /* have to deal with recycling */
222
        sprintf(g_sql_buf[0], "[%s].sdf_data", iname);
223
        int veclen = _get_row_count2(g_sql_buf[0]);
224
 
225
        /* find if there is any TRUE element in the vector */
3281 mrmanese 226
        for (i = 0; i < idxlen && i < veclen; i++) {
3255 mrmanese 227
            if (LOGICAL(idx)[i]) {
228
                sqlite3_bind_int(stmt, 1, i);
229
                sqlite3_step(stmt);
230
                /* there are at least (idxlen-i) TRUE per cycle of the LOGICAL
231
                 * index. there are at least (veclen/idxlen) cycles (int div).
232
                 * at the last cycle, if (veclen%idxlen > 0), there will be
233
                 * at least (veclen%idxlen - i) if veclen%idxlen > i */
234
                retlen = (idxlen-i) * (veclen/idxlen);
235
                if (veclen%idxlen > i) retlen += (veclen%idxlen - i);
236
 
237
                /* create the vector */
238
                retlen = _get_vector_index_typed_result(stmt, &ret, retlen);
239
                break;
240
            }
241
        }
242
 
3281 mrmanese 243
        if (i < idxlen && i < veclen) {
3255 mrmanese 244
            for (i++; i < veclen; i++) {
245
                if (LOGICAL(idx)[i%idxlen]) {
246
                    sqlite3_reset(stmt);
247
                    sqlite3_bind_int(stmt, 1, i);
248
                    sqlite3_step(stmt);
249
                    retlen += _get_vector_index_typed_result(stmt, &ret, retlen);
250
                }
251
            }
252
        }
253
    }
254
 
255
    sqlite3_finalize(stmt);
256
 
257
    if (ret != R_NilValue) {
258
        ret = _shrink_vector(ret, retlen);
259
        tmp = GET_LEVELS(svec);
260
        if (tmp != R_NilValue) {
261
            SET_LEVELS(ret, duplicate(tmp));
262
            if (LENGTH(GET_CLASS(svec)) == 2) {
263
                SET_CLASS(ret, mkString("factor"));
264
            } else {
265
                PROTECT(tmp = NEW_CHARACTER(2));
266
                SET_STRING_ELT(tmp, 0, mkChar("ordered"));
267
                SET_STRING_ELT(tmp, 1, mkChar("factor"));
268
                UNPROTECT(1);
269
            }
270
        }
271
    }
272
 
273
    return ret;
274
}
275
 
3324 mrmanese 276
/* the global accumulator should be safe if we only do 1 cummulative or
277
 * aggregate at any time. it won't work for stuffs like "select max(col)-min(col)
278
 * from sdf_data". */
279
static double g_accumulator = 0.0; /* accumulator var for cumsum, cumprod, etc. */
280
static int g_start = 0;            /* flag for start of cummulation */
281
static int g_narm = 0;             /* for Summary group */
3255 mrmanese 282
 
3307 mrmanese 283
SEXP sdf_do_variable_math(SEXP func, SEXP vector, SEXP extra_args, SEXP _nargs) {
284
    char *iname, *iname_src, *varname_src, *funcname;
285
    int namelen, res, nargs;
286
    sqlite3_stmt *stmt;
3255 mrmanese 287
 
3307 mrmanese 288
    /* get data from arguments (function name and sqlite.vector stuffs) */
289
    funcname = CHAR_ELT(func, 0);
290
    iname_src = SDF_INAME(vector);
291
    varname_src = SVEC_VARNAME(vector);
292
    nargs = INTEGER(_nargs)[0];
3255 mrmanese 293
 
3324 mrmanese 294
    if (!USE_SDF(iname_src, TRUE)) return R_NilValue;
3308 mrmanese 295
 
3307 mrmanese 296
    /* check nargs */
297
    if (nargs > 2) {
298
        Rprintf("Error: Don't know how to handle Math functions w/ more than 2 args\n");
299
        return R_NilValue;
300
    }
301
 
302
    /* create a new sdf, with 1 column named V1 */
303
    iname = _create_sdf_skeleton2(R_NilValue, &namelen);
304
    if (iname == NULL) return R_NilValue;
305
 
306
    sprintf(g_sql_buf[0], "create table [%s].sdf_data ([row name] text, "
307
            "V1 double)", iname);
308
    res = _sqlite_exec(g_sql_buf[0]);
309
    _sqlite_error(res);
310
 
311
    /* insert into <newsdf>.col, row.names select func(col), rownames */
312
    sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
313
            "select [row name], %s([%s]) from [%s].sdf_data", iname, funcname,
314
            varname_src, iname_src);
315
 
316
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0); 
317
    if (_sqlite_error(res)) {
318
        sprintf(g_sql_buf[0], "detach %s", iname);
319
        _sqlite_exec(g_sql_buf[0]);
320
 
321
        /* we will return a string with the file name, and do file.remove
322
         * at R */
323
        iname[namelen] = '.';
324
        return mkString(iname);
325
    }
326
 
3324 mrmanese 327
    g_accumulator = 0.0;   /* initialize accumulator */
328
    g_start = 1;           /* flag that we are at start of accumulating */
3307 mrmanese 329
    sqlite3_step(stmt);
330
    sqlite3_finalize(stmt);
331
 
332
    /* create sqlite.vector sexp */
333
    SEXP ret, value; int nprotected = 0;
334
    PROTECT(ret = NEW_LIST(2)); nprotected++;
335
 
336
    /* set list names */
337
    PROTECT(value = NEW_CHARACTER(2)); nprotected++;
338
    SET_STRING_ELT(value, 0, mkChar("iname"));
339
    SET_STRING_ELT(value, 1, mkChar("varname"));
340
    SET_NAMES(ret, value);
341
 
342
    /* set list values */
343
    SET_VECTOR_ELT(ret, 0, mkString(iname));
344
    SET_VECTOR_ELT(ret, 1, mkString("V1"));
345
 
346
    /* set sexp class */
347
    PROTECT(value = NEW_CHARACTER(2)); nprotected++;
348
    SET_VECTOR_ELT(value, 0, mkChar("sqlite.vector"));
349
    SET_VECTOR_ELT(value, 1, mkChar("numeric"));
350
    SET_CLASS(ret, value);
351
 
352
    UNPROTECT(nprotected);
353
 
354
    return ret;
355
 
356
}
357
 
3324 mrmanese 358
SEXP sdf_do_variable_summary(SEXP func, SEXP vector, SEXP na_rm) {
359
    char *iname_src, *varname_src, *funcname;
360
    int res;
361
    sqlite3_stmt *stmt;
362
    double _ret = NA_REAL; SEXP ret;
3307 mrmanese 363
 
3324 mrmanese 364
    /* get data from arguments (function name and sqlite.vector stuffs) */
365
    funcname = CHAR_ELT(func, 0);
366
    iname_src = SDF_INAME(vector);
367
    varname_src = SVEC_VARNAME(vector);
3307 mrmanese 368
 
3324 mrmanese 369
    if (!USE_SDF(iname_src, TRUE)) return R_NilValue;
370
 
371
    g_narm = LOGICAL(na_rm)[0];
372
    if (strcmp(funcname, "range") == 0) {
373
        /* special handling for range. use min then max */
374
        g_start = 1;
375
        g_accumulator = 0.0;
376
        sprintf(g_sql_buf[0], "select min_df([%s]) from [%s].sdf_data", varname_src, iname_src);
377
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
378
        if (_sqlite_error(res)) return R_NilValue;
379
        sqlite3_step(stmt); sqlite3_finalize(stmt);
380
        _ret = g_accumulator;
381
 
382
        if (R_IsNA(_ret) && !g_narm) {
383
            PROTECT(ret = NEW_NUMERIC(2));
384
            REAL(ret)[0] = REAL(ret)[1] = R_NaReal;
385
            goto __sdf_do_variable_summary_out;
386
        }
387
 
388
        g_start = 1;
389
        g_accumulator = 0.0;
390
        sprintf(g_sql_buf[0], "select max_df([%s]) from [%s].sdf_data", varname_src, iname_src);
391
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
392
        if (_sqlite_error(res)) return R_NilValue;
393
        sqlite3_step(stmt); sqlite3_finalize(stmt);
394
 
395
        /* if there is NA, then the if above should have caught it already */
396
        PROTECT(ret = NEW_NUMERIC(2));
397
        REAL(ret)[0] = _ret;
398
        REAL(ret)[1] = g_accumulator;
399
    } else {
400
        g_start = 1;  /* we'll use these instead of sqlite3_aggregate_context */
401
        g_accumulator = 0.0;
402
        sprintf(g_sql_buf[0], "select %s_df([%s]) from [%s].sdf_data", funcname, varname_src, iname_src);
403
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
404
        if (_sqlite_error(res)) return R_NilValue;
405
        res = sqlite3_step(stmt); sqlite3_finalize(stmt);
406
 
407
        if (strcmp(funcname, "all") == 0 || strcmp(funcname, "any") == 0) {
408
            PROTECT(ret = NEW_LOGICAL(1));
409
            if (R_IsNA(g_accumulator)) LOGICAL(ret)[0] = NA_INTEGER;
410
            else LOGICAL(ret)[0] = !(g_accumulator == 0);
411
        } else {
412
            PROTECT(ret = NEW_NUMERIC(1));
413
            REAL(ret)[0] = g_accumulator;
414
        }
415
    }
416
 
417
__sdf_do_variable_summary_out:
418
    UNPROTECT(1);
419
    return ret;
420
}
421
 
422
 
3307 mrmanese 423
/****************************************************************************
424
 * VECTOR MATH/OPS/GROUP OPERATIONS
425
 ****************************************************************************/
3324 mrmanese 426
 
3307 mrmanese 427
int __vecmath_checkarg(sqlite3_context *ctx, sqlite3_value *arg, double *value) {
428
    int ret = 1;
429
    if (sqlite3_value_type(arg) == SQLITE_NULL) { 
430
        sqlite3_result_null(ctx); 
431
        ret = 0;
432
    } else {
433
        if (sqlite3_value_type(arg) == SQLITE_INTEGER) 
434
            *value = sqlite3_value_int(arg); 
435
        else *value = sqlite3_value_double(arg); 
436
    }
437
    return ret;
438
}
439
 
440
#define SQLITE_MATH_FUNC1(name, func) static void __vecmath_ ## name(\
441
        sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
442
    double value; \
443
    if (__vecmath_checkarg(ctx, argv[0], &value)) { \
444
        sqlite3_result_double(ctx, func(value)); \
445
    }  \
446
}
447
 
3324 mrmanese 448
#define SQLITE_MATH_FUNC_CUM(name, func) static void __vecmath_ ## name(\
449
        sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
450
    double value; \
451
    if (__vecmath_checkarg(ctx, argv[0], &value)) { \
452
        if (g_start) { g_start = 0; g_accumulator = value; } \
453
        else g_accumulator = func(g_accumulator, value); \
454
        sqlite3_result_double(ctx, g_accumulator); \
455
    }  \
456
}
457
 
3307 mrmanese 458
/* SQLITE_MATH_FUNC1(abs, abs)   in SQLite */
459
SQLITE_MATH_FUNC1(sign, sign)   /* in R */
460
SQLITE_MATH_FUNC1(sqrt, sqrt)
461
SQLITE_MATH_FUNC1(floor, floor)
462
SQLITE_MATH_FUNC1(ceiling, ceil)
463
SQLITE_MATH_FUNC1(trunc, ftrunc) /* in R */
464
/* SQLITE_MATH_FUNC1(round, )   in SQLite */
465
/* SQLITE_MATH_FUNC1(signif, ) 2 arg */
466
SQLITE_MATH_FUNC1(exp, exp)
467
/* SQLITE_MATH_FUNC1(log, ) 2 arg */
468
SQLITE_MATH_FUNC1(cos, cos)
469
SQLITE_MATH_FUNC1(sin, sin)
470
SQLITE_MATH_FUNC1(tan, tan)
471
SQLITE_MATH_FUNC1(acos, acos)
472
SQLITE_MATH_FUNC1(asin, asin)
473
SQLITE_MATH_FUNC1(atan, atan)
474
SQLITE_MATH_FUNC1(cosh, cosh)
475
SQLITE_MATH_FUNC1(sinh, sinh)
476
SQLITE_MATH_FUNC1(tanh, tanh)
477
SQLITE_MATH_FUNC1(acosh, acosh)  /* nowhere in include?? */
478
SQLITE_MATH_FUNC1(asinh, asinh)  /* nowhere in include?? */
479
SQLITE_MATH_FUNC1(atanh, atanh)  /* nowhere in include?? */
480
SQLITE_MATH_FUNC1(lgamma, lgammafn) /* in R */
481
SQLITE_MATH_FUNC1(gamma, gammafn) /* in R */
482
/* SQLITE_MATH_FUNC1(gammaCody, gammaCody)   * in R ?? */
483
SQLITE_MATH_FUNC1(digamma, digamma) /* in R */    
484
SQLITE_MATH_FUNC1(trigamma, trigamma) /* in R */
485
 
3324 mrmanese 486
#define SUM(a, b)  (a) + (b)
487
#define PROD(a, b) (a) * (b)
488
#define MIN(a, b) ((a) <= (b)) ? (a) : (b)
489
#define MAX(a, b) ((a) >= (b)) ? (a) : (b)
490
#define ALL(a, b) (((a) == 0) || ((b) == 0)) ? 0 : 1
491
#define ANY(a, b) (((a) == 0) && ((b) == 0)) ? 0 : 1
492
 
493
SQLITE_MATH_FUNC_CUM(cumsum, SUM)
494
SQLITE_MATH_FUNC_CUM(cumprod, PROD)
495
SQLITE_MATH_FUNC_CUM(cummin, MIN)
496
SQLITE_MATH_FUNC_CUM(cummax, MAX)
497
 
498
#define SQLITE_SUMMARY_FUNC(name, func) static void __vecsummary_ ## name(\
499
        sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
500
    double value; \
501
    if (!g_narm && R_IsNA(g_accumulator)) return; /* NA if na.rm=F & NA found */ \
502
    if (sqlite3_value_type(argv[0]) != SQLITE_NULL) {  \
503
        if (sqlite3_value_type(argv[0]) == SQLITE_INTEGER) {  \
504
            int tmp = sqlite3_value_int(argv[0]); \
505
            value = (tmp == NA_INTEGER) ? R_NaReal : tmp; \
506
        } else value = sqlite3_value_double(argv[0]);  \
507
        if (R_IsNA(value)) { \
508
            if (!g_narm) g_accumulator = value; return; \
509
        } else if (g_start) { g_start = 0; g_accumulator = value; } \
510
        else g_accumulator = func(g_accumulator, value); \
511
    } \
512
}
513
 
514
SQLITE_SUMMARY_FUNC(all_df, ALL)
515
SQLITE_SUMMARY_FUNC(any_df, ANY)
516
SQLITE_SUMMARY_FUNC(sum_df, SUM)
517
SQLITE_SUMMARY_FUNC(prod_df, PROD)
518
SQLITE_SUMMARY_FUNC(min_df, MIN)
519
SQLITE_SUMMARY_FUNC(max_df, MAX)
520
 
521
static void __vecsummary_finalize(sqlite3_context *ctx) {
522
    /* g_accumulator already summarizes it. just return that */
523
    sqlite3_result_double(ctx, g_accumulator);
524
}
525
 
3307 mrmanese 526
#define VMENTRY1(func)  {#func, __vecmath_ ## func}
3324 mrmanese 527
#define VSENTRY1(func)  {#func, __vecsummary_ ## func}
3307 mrmanese 528
void __register_vector_math() {
529
    int i, res;
530
    static const struct {
531
        char *name;
532
        void (*func)(sqlite3_context*, int, sqlite3_value**);
533
    } arr_func1[] = {
534
        VMENTRY1(sign),
535
        VMENTRY1(sqrt),
536
        VMENTRY1(floor),
537
        VMENTRY1(ceiling),
538
        VMENTRY1(trunc),
539
        VMENTRY1(exp),
540
        VMENTRY1(cos),
541
        VMENTRY1(sin),
542
        VMENTRY1(tan),
543
        VMENTRY1(acos),
544
        VMENTRY1(asin),
545
        VMENTRY1(atan),
546
        VMENTRY1(cosh),
547
        VMENTRY1(sinh),
548
        VMENTRY1(tanh),
549
        VMENTRY1(acosh),
550
        VMENTRY1(asinh),
551
        VMENTRY1(atanh),
552
        VMENTRY1(lgamma),
553
        VMENTRY1(gamma),
554
        VMENTRY1(digamma),
3324 mrmanese 555
        VMENTRY1(trigamma),
556
        VMENTRY1(cumsum),
557
        VMENTRY1(cumprod),
558
        VMENTRY1(cummin),
559
        VMENTRY1(cummax)
560
    }, arr_sum1[] = {
561
        VSENTRY1(all_df),  /* can't override sum, min, max */
562
        VSENTRY1(any_df),
563
        VSENTRY1(sum_df),
564
        VSENTRY1(prod_df),
565
        VSENTRY1(min_df),
566
        VSENTRY1(max_df)
3307 mrmanese 567
    };
568
 
3324 mrmanese 569
    int len = sizeof(arr_func1) / sizeof(arr_func1[0]);
3307 mrmanese 570
 
3324 mrmanese 571
    for (i = 0; i < len; i++) {
3307 mrmanese 572
        res = sqlite3_create_function(g_workspace, arr_func1[i].name, 1, 
573
                SQLITE_ANY, NULL, arr_func1[i].func, NULL, NULL);
574
        _sqlite_error(res);
575
    }
3324 mrmanese 576
 
577
    len = sizeof(arr_sum1) / sizeof(arr_sum1[0]);
578
    for (i = 0; i < len; i++) {
579
        res = sqlite3_create_function(g_workspace, arr_sum1[i].name, 1, 
580
                SQLITE_ANY, NULL, NULL, arr_sum1[i].func, __vecsummary_finalize);
581
        _sqlite_error(res);
582
    }
3307 mrmanese 583
}