The R Project SVN R-packages

Rev

Rev 3855 | Rev 4590 | 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
 
3358 mrmanese 5
/****************************************************************************
6
 * UTILITY FUNCTIONS
7
 ****************************************************************************/
3419 mrmanese 8
char *_create_svector1(SEXP name, const char *type, int * _namelen, int protect) {
3358 mrmanese 9
    int namelen, res;
3419 mrmanese 10
    char *iname = _create_sdf_skeleton1(name, &namelen, protect);
3255 mrmanese 11
 
3358 mrmanese 12
    if (iname == NULL) return NULL;
3255 mrmanese 13
 
3358 mrmanese 14
    sprintf(g_sql_buf[2], "create table [%s].sdf_data ([row name] text, "
15
            "V1 %s, primary key ([row name]))", iname, type);
16
    res = _sqlite_exec(g_sql_buf[2]);
17
    _sqlite_error(res);
3308 mrmanese 18
 
3358 mrmanese 19
    if (_namelen != NULL) *_namelen = namelen;
20
    return iname;
21
}
3255 mrmanese 22
 
3684 mrmanese 23
SEXP _create_svector_sexp(const char *iname, const char *tblname,
24
        const char *varname, const char *type) {
3358 mrmanese 25
    SEXP ret, value; int nprotected = 0;
3684 mrmanese 26
    PROTECT(ret = NEW_LIST(3)); nprotected++;
3255 mrmanese 27
 
28
    /* set list names */
3684 mrmanese 29
    PROTECT(value = NEW_CHARACTER(3)); nprotected++;
3255 mrmanese 30
    SET_STRING_ELT(value, 0, mkChar("iname"));
3684 mrmanese 31
    SET_STRING_ELT(value, 1, mkChar("tblname"));
32
    SET_STRING_ELT(value, 2, mkChar("varname"));
3255 mrmanese 33
    SET_NAMES(ret, value);
34
 
35
    /* set list values */
36
    SET_VECTOR_ELT(ret, 0, mkString(iname));
3684 mrmanese 37
    SET_VECTOR_ELT(ret, 1, mkString(tblname));
38
    SET_VECTOR_ELT(ret, 2, mkString(varname));
3255 mrmanese 39
 
3358 mrmanese 40
    /* set sexp class */
3456 mrmanese 41
    SET_CLASS(ret, mkString("sqlite.vector"));
3255 mrmanese 42
 
3456 mrmanese 43
    /* set sdf.vector.type */
44
    SET_SDFVECTORTYPE(ret, mkString(type));
45
 
3255 mrmanese 46
    UNPROTECT(nprotected);
3358 mrmanese 47
 
3255 mrmanese 48
    return ret;
49
}
50
 
4160 mrmanese 51
/* if ret == NULL, 3rd arg is the length of the vector to be created. otherwise
3358 mrmanese 52
 * it is the index in the vector ret where we will put the result extracted
53
 * from ret */
4160 mrmanese 54
int _get_vector_index_typed_result(sqlite3_stmt *stmt, SEXP *ret, int colidx,
55
        int idx_or_len, int *coltype) {
56
    int added = 1, ctype;
3255 mrmanese 57
    if (*ret == NULL || *ret == R_NilValue) {
4160 mrmanese 58
        if ((ctype = sqlite3_column_type(stmt, colidx)) == SQLITE_NULL) {
3255 mrmanese 59
            added = 0;
60
        }
61
 
4160 mrmanese 62
        if (ctype == SQLITE_TEXT) {
3255 mrmanese 63
            PROTECT(*ret = NEW_CHARACTER(idx_or_len));
64
            if (added) 
4160 mrmanese 65
                SET_STRING_ELT(*ret, 0, mkChar((char *)sqlite3_column_text(stmt, colidx)));
66
        } else if (ctype == SQLITE_FLOAT) {
3255 mrmanese 67
            PROTECT(*ret = NEW_NUMERIC(idx_or_len));
4160 mrmanese 68
            if (added) REAL(*ret)[0] = sqlite3_column_double(stmt, colidx);
69
        } else if (ctype == SQLITE_INTEGER) {
70
            /* sqlite does not differentiate b/w ints & bits, so we have to
71
             * do it ourselves since R distinguishes b/w ints & logicals */
72
            if (strcmp(sqlite3_column_decltype(stmt, colidx), "bit") == 0) {
73
                ctype = SQLITEDF_BIT; 
74
                PROTECT(*ret = NEW_LOGICAL(idx_or_len));
75
                if (added) LOGICAL(*ret)[0] = sqlite3_column_int(stmt, colidx);
76
            } else {
77
                PROTECT(*ret = NEW_INTEGER(idx_or_len));
78
                if (added) INTEGER(*ret)[0] = sqlite3_column_int(stmt, colidx);
79
            }
3255 mrmanese 80
        } else added = 0;
81
 
4160 mrmanese 82
        if (added) UNPROTECT(1);
83
        *coltype = ctype;
3684 mrmanese 84
    } else if (stmt != NULL) {
4160 mrmanese 85
        int ctype = *coltype;
86
 
87
        /* first row must have been NULL so that *coltype was not set */
88
        if (ctype == SQLITE_NULL) {
89
            ctype = *coltype = sqlite3_column_type(stmt, colidx);
90
            /* distinguish int or logical */
91
            if (ctype == SQLITE_INTEGER) 
92
                ctype = (strcmp(sqlite3_column_decltype(stmt, colidx), "bit") == 0) ?
93
                    SQLITEDF_BIT : SQLITE_INTEGER;
94
        }
95
 
96
        if (sqlite3_column_type(stmt, colidx) == SQLITE_NULL) {
3255 mrmanese 97
            added = 0;
4160 mrmanese 98
        } else if (ctype == SQLITE_TEXT) {
3255 mrmanese 99
            SET_STRING_ELT(*ret, idx_or_len, 
4160 mrmanese 100
                    mkChar((char *)sqlite3_column_text(stmt, colidx)));
101
        } else if (ctype == SQLITE_FLOAT) {
102
            REAL(*ret)[idx_or_len] = sqlite3_column_double(stmt, colidx);
103
        } else if (ctype == SQLITE_INTEGER) {
104
            INTEGER(*ret)[idx_or_len] = sqlite3_column_int(stmt, colidx);
105
        } else if (ctype == SQLITEDF_BIT) {
106
            LOGICAL(*ret)[idx_or_len] = sqlite3_column_int(stmt, colidx);
3255 mrmanese 107
        } else added = 0;
3684 mrmanese 108
    } else if (stmt == NULL) {
4160 mrmanese 109
        /* used when there is no row returned (sqlite3_step(stmt)!= QLITE_ROW),
110
         * and we just insert NAs in the result */
111
        ctype = *coltype;
112
        if (ctype == SQLITE_NULL) { 
113
            /* since stmt == NULL, we can't check its column type */
3684 mrmanese 114
            added = 0;
4160 mrmanese 115
        } else if (ctype == SQLITE_TEXT) {
3684 mrmanese 116
            SET_STRING_ELT(*ret, idx_or_len, NA_STRING);
4160 mrmanese 117
        } else if (ctype == SQLITE_FLOAT) {
3684 mrmanese 118
            REAL(*ret)[idx_or_len] = NA_REAL;
4160 mrmanese 119
        } else if (ctype == SQLITE_INTEGER) {
3684 mrmanese 120
            INTEGER(*ret)[idx_or_len] = NA_INTEGER;
4160 mrmanese 121
        } else if (ctype == SQLITEDF_BIT) {
122
            LOGICAL(*ret)[idx_or_len] = NA_LOGICAL;
3684 mrmanese 123
        } else added = 0;
3255 mrmanese 124
    }
125
 
126
    return added;
127
}
128
 
3358 mrmanese 129
/****************************************************************************
130
 * SVEC FUNCTIONS
131
 ****************************************************************************/
132
SEXP sdf_get_variable(SEXP sdf, SEXP name) {
3456 mrmanese 133
    char *iname, *varname, *svec_type = NULL;
134
    const char *coltype;
135
    int type = -1, res, nprotected = 0;
136
    SEXP ret, value;
137
 
3358 mrmanese 138
    if (!IS_CHARACTER(name)) {
3471 mrmanese 139
        error("argument is not a string.\n");
3358 mrmanese 140
    }
141
 
3456 mrmanese 142
    iname = SDF_INAME(sdf);
143
    varname = CHAR_ELT(name, 0);
3358 mrmanese 144
 
3419 mrmanese 145
    if (!USE_SDF1(iname, TRUE, FALSE)) return R_NilValue;
3358 mrmanese 146
 
147
    /* check if sdf & varname w/in that sdf exists */
148
    sqlite3_stmt *stmt;
149
    sprintf(g_sql_buf[0], "select [%s] from [%s].sdf_data", varname, iname);
150
 
3456 mrmanese 151
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
3358 mrmanese 152
 
153
    if (_sqlite_error(res)) return R_NilValue;
154
 
3456 mrmanese 155
    coltype = sqlite3_column_decltype(stmt, 0);
3358 mrmanese 156
    sqlite3_finalize(stmt);
3456 mrmanese 157
 
3684 mrmanese 158
    PROTECT(ret = NEW_LIST(3)); nprotected++;
3358 mrmanese 159
 
160
    /* set list names */
3684 mrmanese 161
    PROTECT(value = NEW_CHARACTER(3)); nprotected++;
3358 mrmanese 162
    SET_STRING_ELT(value, 0, mkChar("iname"));
3684 mrmanese 163
    SET_STRING_ELT(value, 1, mkChar("tblname"));
164
    SET_STRING_ELT(value, 2, mkChar("varname"));
3358 mrmanese 165
    SET_NAMES(ret, value);
166
 
167
    /* set list values */
168
    SET_VECTOR_ELT(ret, 0, mkString(iname));
3684 mrmanese 169
    SET_VECTOR_ELT(ret, 1, mkString("sdf_data"));
170
    SET_VECTOR_ELT(ret, 2, mkString(varname));
3358 mrmanese 171
 
172
    /* set class */
3456 mrmanese 173
    if (strcmp(coltype, "text") == 0) svec_type = "character";
174
    else if (strcmp(coltype, "double") == 0) svec_type = "numeric";
175
    else if (strcmp(coltype, "bit") == 0) svec_type = "logical";
3358 mrmanese 176
    else if (strcmp(coltype, "integer") == 0 || strcmp(coltype, "int") == 0) {
177
        /* determine if int, factor or ordered */
4160 mrmanese 178
        type = _get_factor_levels1(iname, varname, ret, FALSE);
3358 mrmanese 179
        switch(type) {
3456 mrmanese 180
            case VAR_INTEGER: svec_type = "integer"; break;
181
            case VAR_FACTOR: svec_type = "factor"; break;
182
            case VAR_ORDERED: svec_type = "ordered";
3358 mrmanese 183
        }
184
    }
185
 
3456 mrmanese 186
    SET_CLASS(ret, mkString("sqlite.vector"));
187
    SET_SDFVECTORTYPE(ret, mkString(svec_type));
3358 mrmanese 188
 
189
    UNPROTECT(nprotected);
190
    return ret;
191
 
192
}
193
 
194
 
3255 mrmanese 195
SEXP sdf_get_variable_length(SEXP svec) {
196
    char *iname = SDF_INAME(svec);
3419 mrmanese 197
    if (!USE_SDF1(iname, TRUE, FALSE)) return R_NilValue;
3255 mrmanese 198
 
3446 mrmanese 199
    return ScalarInteger(_get_row_count2(iname, 1));
3255 mrmanese 200
}
201
 
202
 
203
SEXP sdf_get_variable_index(SEXP svec, SEXP idx) {
204
    SEXP ret = R_NilValue, tmp;
3684 mrmanese 205
    char *iname = SDF_INAME(svec), *tblname = SVEC_TBLNAME(svec),
206
         *varname = SVEC_VARNAME(svec);
4160 mrmanese 207
    int index, idxlen, i, retlen=0, res, coltype;
3358 mrmanese 208
    sqlite3_stmt *stmt;
3255 mrmanese 209
 
3419 mrmanese 210
    if (!USE_SDF1(iname, TRUE, FALSE)) return R_NilValue;
3308 mrmanese 211
 
3255 mrmanese 212
    idxlen = LENGTH(idx);
213
    if (idxlen < 1) return ret;
214
 
4160 mrmanese 215
    sprintf(g_sql_buf[0], "select [%s] from [%s].[%s] where rowid=?",
3684 mrmanese 216
            varname, iname, tblname);
3255 mrmanese 217
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
3684 mrmanese 218
    if (_sqlite_error(res)) error("cannot complete request");
3255 mrmanese 219
 
220
    /* get data based on index */
221
    if (IS_NUMERIC(idx)) {
4160 mrmanese 222
        /* special handling of 1st index, bec this is where we create the
223
         * SEXP to be used to hold the result */
224
        index = (int) REAL(idx)[0];
225
        if (index < 1 && idxlen == 1) return ret;
3255 mrmanese 226
 
4160 mrmanese 227
        if (index >= 1) {
3255 mrmanese 228
            sqlite3_bind_int(stmt, 1, index);
229
            res = sqlite3_step(stmt);
230
            if (res == SQLITE_ROW) { 
4160 mrmanese 231
                retlen = _get_vector_index_typed_result(stmt, &ret, 0, idxlen, &coltype);
3255 mrmanese 232
            } 
233
        } 
234
 
4160 mrmanese 235
        if (index < 1 || res != SQLITE_ROW) {
3255 mrmanese 236
            /* something wrong w/ 1st idx, and it is quietly ignored. we make 
237
             * a "dummy" call to setup the SEXP */
3358 mrmanese 238
            sqlite3_reset(stmt);
3255 mrmanese 239
            sqlite3_bind_int(stmt, 1, 0);
3358 mrmanese 240
            res = sqlite3_step(stmt);
241
            if (res == SQLITE_ROW) {
4160 mrmanese 242
                /* populate with 1st row. this should be overwritten by 
243
                 * succeeding calls. if there are no valid result, then 
244
                 * everything will be removed by _shrink_vector().
245
                 */
246
                _get_vector_index_typed_result(stmt, &ret, 0, idxlen - 1, &coltype);
3358 mrmanese 247
            }
3255 mrmanese 248
            retlen = 0;
249
        }
250
 
3358 mrmanese 251
 
3255 mrmanese 252
        if (idxlen > 1) {
253
            for (i = 1; i < idxlen; i++) {
4160 mrmanese 254
                index = (int) REAL(idx)[i];
255
                if (index < 1) continue;
3255 mrmanese 256
                sqlite3_reset(stmt);
257
                sqlite3_bind_int(stmt, 1, index);
258
                res = sqlite3_step(stmt);
3684 mrmanese 259
                if (res == SQLITE_ROW) {
4160 mrmanese 260
                    retlen += _get_vector_index_typed_result(stmt, &ret, 0, retlen, &coltype); 
3684 mrmanese 261
                } else {
4160 mrmanese 262
                    retlen += _get_vector_index_typed_result(NULL, &ret, 0, retlen, &coltype); 
3684 mrmanese 263
                }
3255 mrmanese 264
            }
265
        }
266
    } else if (IS_INTEGER(idx)) {
267
        /* similar to REAL (IS_NUMERIC) above, except that we don't have
268
         * to cast idx to int. can't refactor this out, sucks. */
4160 mrmanese 269
        index = INTEGER(idx)[0];
270
        if (index < 1 && idxlen == 1) return ret;
3255 mrmanese 271
 
4160 mrmanese 272
        if (index >= 1) {
3255 mrmanese 273
            sqlite3_bind_int(stmt, 1, index);
3281 mrmanese 274
            res = sqlite3_step(stmt);
275
            if (res == SQLITE_ROW) { 
4160 mrmanese 276
                retlen = _get_vector_index_typed_result(stmt, &ret, 0, idxlen, &coltype);
3281 mrmanese 277
            } 
278
        } 
279
 
4160 mrmanese 280
        if (index < 1 || res != SQLITE_ROW) {
3281 mrmanese 281
            /* something wrong w/ 1st idx, and it is quietly ignored. we make 
282
             * a "dummy" call to setup the SEXP */
3358 mrmanese 283
            sqlite3_reset(stmt);
3255 mrmanese 284
            sqlite3_bind_int(stmt, 1, 0);
3358 mrmanese 285
            res = sqlite3_step(stmt);
286
            if (res == SQLITE_ROW) {
4160 mrmanese 287
                _get_vector_index_typed_result(stmt, &ret, 0, idxlen - 1, &coltype);
3358 mrmanese 288
            }
3255 mrmanese 289
            retlen = 0;
290
        }
291
 
292
        if (idxlen > 1) {
293
            for (i = 1; i < idxlen; i++) {
4160 mrmanese 294
                index = INTEGER(idx)[i];
295
                if (index < 1) continue;
3255 mrmanese 296
                sqlite3_reset(stmt);
297
                sqlite3_bind_int(stmt, 1, index);
3684 mrmanese 298
                res = sqlite3_step(stmt);
299
                if (res == SQLITE_ROW) {
4160 mrmanese 300
                    retlen += _get_vector_index_typed_result(stmt, &ret, 0, retlen, &coltype); 
3684 mrmanese 301
                } else {
4160 mrmanese 302
                    retlen += _get_vector_index_typed_result(NULL, &ret, 0, retlen, &coltype);
3684 mrmanese 303
                }
3255 mrmanese 304
            }
305
        }
306
 
307
    } else if (IS_LOGICAL(idx)) {
308
        /* have to deal with recycling */
3358 mrmanese 309
        int veclen = _get_row_count2(iname, 1);
3255 mrmanese 310
 
4160 mrmanese 311
        /* in this indexing, idx[i] == TRUE is equiv to vector[i]. therefore
312
         * idxlen <= veclen. if idxlen < veclen, then idx is recycled. */
313
 
3255 mrmanese 314
        /* find if there is any TRUE element in the vector */
4160 mrmanese 315
        for (i = 1; i < idxlen && i < veclen; i++) {
3255 mrmanese 316
            if (LOGICAL(idx)[i]) {
4160 mrmanese 317
                sqlite3_bind_int(stmt, 1, i+1);
3255 mrmanese 318
                sqlite3_step(stmt);
319
                /* there are at least (idxlen-i) TRUE per cycle of the LOGICAL
320
                 * index. there are at least (veclen/idxlen) cycles (int div).
321
                 * at the last cycle, if (veclen%idxlen > 0), there will be
322
                 * at least (veclen%idxlen - i) if veclen%idxlen > i */
323
                retlen = (idxlen-i) * (veclen/idxlen);
324
                if (veclen%idxlen > i) retlen += (veclen%idxlen - i);
325
 
326
                /* create the vector */
4160 mrmanese 327
                retlen = _get_vector_index_typed_result(stmt, &ret, 0, retlen, &coltype);
3255 mrmanese 328
                break;
329
            }
330
        }
331
 
3281 mrmanese 332
        if (i < idxlen && i < veclen) {
3255 mrmanese 333
            for (i++; i < veclen; i++) {
334
                if (LOGICAL(idx)[i%idxlen]) {
335
                    sqlite3_reset(stmt);
4160 mrmanese 336
                    sqlite3_bind_int(stmt, 1, i+1);
3684 mrmanese 337
                    res = sqlite3_step(stmt);
338
                    if (res == SQLITE_ROW) {
4160 mrmanese 339
                        retlen += _get_vector_index_typed_result(stmt, &ret, 0, retlen, &coltype);
3684 mrmanese 340
                    } else {
4160 mrmanese 341
                        retlen += _get_vector_index_typed_result(NULL, &ret, 0, retlen, &coltype);
3684 mrmanese 342
                    }
3255 mrmanese 343
                }
344
            }
345
        }
346
    }
347
 
348
    sqlite3_finalize(stmt);
349
 
350
    if (ret != R_NilValue) {
351
        ret = _shrink_vector(ret, retlen);
352
        tmp = GET_LEVELS(svec);
353
        if (tmp != R_NilValue) {
354
            SET_LEVELS(ret, duplicate(tmp));
3456 mrmanese 355
            if (TEST_SDFVECTORTYPE(svec, "factor")) {
3255 mrmanese 356
                SET_CLASS(ret, mkString("factor"));
357
            } else {
358
                PROTECT(tmp = NEW_CHARACTER(2));
359
                SET_STRING_ELT(tmp, 0, mkChar("ordered"));
360
                SET_STRING_ELT(tmp, 1, mkChar("factor"));
361
                UNPROTECT(1);
362
            }
363
        }
364
    }
365
 
366
    return ret;
367
}
368
 
3358 mrmanese 369
/* sqlite.vector.[<- */
370
SEXP sdf_set_variable_index(SEXP svec, SEXP idx, SEXP value) {
4160 mrmanese 371
    int idx_len, val_len, svec_len, i, res;
372
    char *iname = SDF_INAME(svec), *tblname = SVEC_TBLNAME(svec),
373
         *varname = SVEC_VARNAME(svec);
374
    sqlite3_stmt *stmt;
3358 mrmanese 375
 
376
    /* match levels if factor or ordered */
377
    if (inherits(value, "ordered")) {
378
    } else if (inherits(value, "factor")) {
379
    }
380
 
381
    idx_len = LENGTH(idx);
382
    val_len = LENGTH(value);
4160 mrmanese 383
    svec_len = _get_row_count2(iname, TRUE);
3358 mrmanese 384
 
4160 mrmanese 385
    if (idx_len % val_len != 0) 
386
        warning("number of items to replace is not a multiple of replacement length");
387
 
388
    sprintf(g_sql_buf[0], "update [%s].[%s] set [%s]=? where rowid=?",
389
            iname, tblname, varname);
390
    _sqlite_begin;
391
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
392
    if (_sqlite_error(res)) {
393
        error("cannot complete request");
394
        _sqlite_commit;
395
    }
396
 
3358 mrmanese 397
    if (IS_NUMERIC(idx)) {
4160 mrmanese 398
        for (i = 0; i < idx_len; i++) {
399
            /* determine type of svec, cast value to type of it */
400
            /* value can only be of a single type, because it is a vector! */
401
            /* if svec is a factor, value is a string, must check with
402
             * factor levels */
403
        }
3358 mrmanese 404
    } else if (IS_INTEGER(idx)) {
405
    } else if (IS_LOGICAL(idx)) {
406
    }
407
 
4160 mrmanese 408
    _sqlite_commit;
3358 mrmanese 409
    return R_NilValue;
410
}
411
 
3419 mrmanese 412
SEXP sdf_variable_summary(SEXP svec, SEXP maxsum) {
3684 mrmanese 413
    char *iname, *tblname, *varname, *type;
3419 mrmanese 414
    sqlite3_stmt *stmt;
415
    int nprotected = 0;
416
    SEXP ret, names;
417
 
418
    iname = SDF_INAME(svec);
3684 mrmanese 419
    tblname = SVEC_TBLNAME(svec);
3419 mrmanese 420
    varname = SVEC_VARNAME(svec);
421
    USE_SDF1(iname, TRUE, FALSE);
422
 
3456 mrmanese 423
    if ((TEST_SDFVECTORTYPE(svec, "ordered") && ((type = "ordered"))) ||
424
            (TEST_SDFVECTORTYPE(svec, "factor") && ((type = "factor")))) {
3419 mrmanese 425
        int nrows, i, max_rows = INTEGER(maxsum)[0];
426
 
427
 
428
        sprintf(g_sql_buf[0], "[%s].[%s %s]", iname, type, varname);
429
        nrows = _get_row_count2(g_sql_buf[0], FALSE);
430
        if (nrows <= max_rows) max_rows = nrows;
431
        else { nrows = max_rows; max_rows--; }
432
 
433
        PROTECT(ret = NEW_INTEGER(nrows)); nprotected = 1;
434
        PROTECT(names = NEW_CHARACTER(nrows)); nprotected++;
435
 
436
        sprintf(g_sql_buf[0], "select [%s].[%s %s].label, count(*) from "
3684 mrmanese 437
                "[%s].[%s] join [%s].[%s %s] on [%s].[%s].[%s]=[%s].[%s %s].level "
438
                "group by [%s].[%s].[%s], [%s].[%s %s].level order by count(*) desc",
439
                iname, type, varname, iname, tblname, iname, type, varname, iname, tblname, varname,
440
                iname, type, varname, iname, tblname, varname, iname, type, varname);
3419 mrmanese 441
        sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
442
 
443
        for (i = 0; i < max_rows; i++) {
444
            sqlite3_step(stmt);
445
            SET_STRING_ELT(names, i, mkChar((char *)sqlite3_column_text(stmt, 0)));
446
            INTEGER(ret)[i] = sqlite3_column_int(stmt, 1);
447
        }
448
 
449
        if (nrows > max_rows) {
450
            int others_sum = 0;
451
            SET_STRING_ELT(names, nrows-1, mkChar("(Others)"));
452
            while (sqlite3_step(stmt) == SQLITE_ROW) {
453
                others_sum += sqlite3_column_int(stmt, 1);
454
            }
455
            INTEGER(ret)[nrows-1] = others_sum;
456
        }
3456 mrmanese 457
    } else if (TEST_SDFVECTORTYPE(svec, "logical")) {
3419 mrmanese 458
        sprintf(g_sql_buf[0], "select count(*) from "
3684 mrmanese 459
                "[%s].[%s] group by [%s] order by [%s]", iname, tblname, varname, varname);
3419 mrmanese 460
 
461
        PROTECT(names = NEW_CHARACTER(3)); nprotected = 1;
462
        PROTECT(ret = NEW_CHARACTER(3)); nprotected++;
463
 
464
        SET_STRING_ELT(names, 0, mkChar("Mode"));
465
        SET_STRING_ELT(names, 1, mkChar("FALSE"));
466
        SET_STRING_ELT(names, 2, mkChar("TRUE"));
467
 
468
        sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
469
        SET_STRING_ELT(ret, 0, mkChar("logical"));
470
        sqlite3_step(stmt);
471
        SET_STRING_ELT(ret, 1, mkChar((const char *)sqlite3_column_text(stmt, 0)));
472
        sqlite3_step(stmt);
473
        SET_STRING_ELT(ret, 2, mkChar((const char *)sqlite3_column_text(stmt, 0)));
474
 
475
    } else return R_NilValue;
476
 
477
    sqlite3_finalize(stmt);
478
    SET_NAMES(ret, names);
479
    SET_CLASS(ret, mkString("table"));
480
    UNPROTECT(nprotected);
481
    return ret;
482
}
483
 
484
 
3324 mrmanese 485
/* the global accumulator should be safe if we only do 1 cummulative or
486
 * aggregate at any time. it won't work for stuffs like "select max(col)-min(col)
487
 * from sdf_data". */
3432 mrmanese 488
static long double g_accumulator = 0.0; /* accumulator var for cumsum, cumprod, etc. */
3324 mrmanese 489
static int g_start = 0;            /* flag for start of cummulation */
490
static int g_narm = 0;             /* for Summary group */
3255 mrmanese 491
 
3473 mrmanese 492
void _init_sqlite_function_accumulator() {
493
    g_accumulator = 0.0;   /* initialize accumulator */
494
    g_start = 1;           /* flag that we are at start of accumulating */
495
}
496
 
3434 mrmanese 497
SEXP sdf_do_variable_math(SEXP func, SEXP vector, SEXP other_args) {
3307 mrmanese 498
    char *iname, *iname_src, *varname_src, *funcname;
3434 mrmanese 499
    int namelen, res;
3307 mrmanese 500
    sqlite3_stmt *stmt;
3255 mrmanese 501
 
3307 mrmanese 502
    /* get data from arguments (function name and sqlite.vector stuffs) */
503
    funcname = CHAR_ELT(func, 0);
504
    iname_src = SDF_INAME(vector);
505
    varname_src = SVEC_VARNAME(vector);
3255 mrmanese 506
 
3419 mrmanese 507
    if (!USE_SDF1(iname_src, TRUE, TRUE)) return R_NilValue;
3308 mrmanese 508
 
3307 mrmanese 509
    /* create a new sdf, with 1 column named V1 */
3419 mrmanese 510
    iname = _create_svector1(R_NilValue, "double", &namelen, TRUE);
3307 mrmanese 511
 
512
    /* insert into <newsdf>.col, row.names select func(col), rownames */
3434 mrmanese 513
    if (strcmp(funcname, "round") == 0 || strcmp(funcname, "signif") == 0) {
514
        double digits = REAL(_getListElement(other_args, "digits"))[0];
515
        sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
516
                "select [row name], %s([%s],?) from [%s].sdf_data", iname, funcname,
517
                varname_src, iname_src);
518
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0); 
519
        if (_sqlite_error(res)) goto vecmath_prepare_error;
520
        res = sqlite3_bind_double(stmt, 1, digits);
521
    } else if (strcmp(funcname, "log") == 0) {
522
        double base = REAL(_getListElement(other_args, "base"))[0];
523
        sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
524
                "select [row name], %s([%s],?) from [%s].sdf_data", iname, funcname,
525
                varname_src, iname_src);
526
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0); 
527
        if (_sqlite_error(res)) goto vecmath_prepare_error;
528
        res = sqlite3_bind_double(stmt, 1, base);
529
    } else {
530
        sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
531
                "select [row name], %s([%s]) from [%s].sdf_data", iname, funcname,
532
                varname_src, iname_src);
533
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0); 
534
    }
3307 mrmanese 535
 
536
    if (_sqlite_error(res)) {
3434 mrmanese 537
vecmath_prepare_error:
3307 mrmanese 538
        sprintf(g_sql_buf[0], "detach %s", iname);
539
        _sqlite_exec(g_sql_buf[0]);
540
 
541
        /* we will return a string with the file name, and do file.remove
542
         * at R */
543
        iname[namelen] = '.';
544
        return mkString(iname);
545
    }
546
 
3473 mrmanese 547
    _init_sqlite_function_accumulator();
3307 mrmanese 548
    sqlite3_step(stmt);
549
    sqlite3_finalize(stmt);
550
 
3419 mrmanese 551
    UNUSE_SDF2(iname);
552
    UNUSE_SDF2(iname_src);
553
 
3684 mrmanese 554
    return _create_svector_sexp(iname, "sdf_data", "V1", "numeric");
3358 mrmanese 555
}
3307 mrmanese 556
 
3434 mrmanese 557
SEXP sdf_do_variable_op(SEXP func, SEXP vector, SEXP op2, SEXP arg_reversed) {
3358 mrmanese 558
    char *iname = NULL, *iname_src, *varname_src, *funcname;
3434 mrmanese 559
    int res, functype = -1, op2_len, svec_len, i, reversed;
3358 mrmanese 560
    sqlite3_stmt *stmt, *stmt2;
3307 mrmanese 561
 
3358 mrmanese 562
    /* get data from arguments (function name and sqlite.vector stuffs) */
563
    funcname = CHAR_ELT(func, 0);
564
    iname_src = SDF_INAME(vector);
565
    varname_src = SVEC_VARNAME(vector);
3434 mrmanese 566
    reversed = LOGICAL(arg_reversed)[0];
3307 mrmanese 567
 
3419 mrmanese 568
    if (!USE_SDF1(iname_src, TRUE, TRUE)) return R_NilValue;
3358 mrmanese 569
    switch(funcname[0]) {
570
        case '+' :
571
        case '-' :
572
        case '*' :
573
        case '/' :
574
        case '^' :
575
        case '%' : /* %% and %/% */ 
576
            functype = 0; break;  /* output is REAL */
577
        case '&' :
578
        case '|' :
579
        case '!' :  /* ! and != */
580
            if (funcname[1] == 0) { functype = 1; break; }
581
        case '=' :  /* == */
582
        case '<' :  /* < and <= */
583
        case '>' :  /* > and >= */
584
            functype = 2; 
585
    }
3307 mrmanese 586
 
3358 mrmanese 587
    svec_len = _get_row_count2(iname_src, 1);
588
    if (functype == 0 || functype == 2 || (functype == 1 && funcname[0] != '!')) {
589
        char *insert_fmt_string1c, *insert_fmt_string1s;
590
        char *insert_fmt_string2c, *insert_fmt_string2s;
3434 mrmanese 591
        int vec_idx, sdf_idx;
592
 
3419 mrmanese 593
        iname = _create_svector1(R_NilValue, (functype == 0) ? "double" : "bit", NULL, TRUE);
3307 mrmanese 594
 
3434 mrmanese 595
        /* insert_fmt_string prefixes:
596
         * 1 - op2 is an ordinary vector, op2_len = 1, straightforward insert-select
597
         * 2 - op2 is an ordinary vector, op2_len > 1, may need recycling, loop both sides
598
         * s - operator will be printed as string
599
         * c - operator is either INTDIV or RMOD (int division, R modulo). initially, I
600
         *     thought I could cast both op to int then use / and % of sqlite, which is just
601
         *     the 2nd character of the funcname. however, R's INTDIV and casts to int 
602
         *     after division (e.g. 3.5 %/% 1.5 == 2). RMOD operates on doubles too,
603
         *     which is the remainder of the largest int multiple of "divisor"
604
         *     (e.g. 3.5 %% 1.5 = 0.5)
605
         */ 
3358 mrmanese 606
        if (functype == 1) { /* boolean binary operators */
3434 mrmanese 607
            if (!reversed) {
608
                insert_fmt_string1s = "insert into [%s].sdf_data "
609
                            "select [row name], ([%s] != 0) %s (? != 0) from [%s].sdf_data";
610
            } else {
611
                insert_fmt_string1s = "insert into [%s].sdf_data "
612
                            "select [row name], (? != 0) %s ([%s] != 0) from [%s].sdf_data";
613
            }
3358 mrmanese 614
            insert_fmt_string2s = "insert into [%s].sdf_data values(?, (? != 0) %s (? != 0))";
615
            /* no need for char version of fmt_string2, since %% only occurs for functype==0 */
616
            insert_fmt_string1c = insert_fmt_string1s;
617
            insert_fmt_string2c = insert_fmt_string2s;
618
        } else {
3434 mrmanese 619
            if (!reversed) {
620
                insert_fmt_string1s = "insert into [%s].sdf_data "
621
                            "select [row name], [%s] %s ? from [%s].sdf_data";
622
                insert_fmt_string1c = "insert into [%s].sdf_data "
623
                            "select [row name], %s([%s],?) from [%s].sdf_data";
624
            } else {
625
                insert_fmt_string1s = "insert into [%s].sdf_data "
626
                            "select [row name], ? %s [%s] from [%s].sdf_data";
627
                insert_fmt_string1c = "insert into [%s].sdf_data "
628
                            "select [row name], %s(?,[%s]) from [%s].sdf_data";
629
            }
3358 mrmanese 630
            /* fmt_string2c format operator from a char, used for %% and %/% */
3434 mrmanese 631
            insert_fmt_string2c = "insert into [%s].sdf_data values(?, %s(?,?))";
3358 mrmanese 632
            insert_fmt_string2s = "insert into [%s].sdf_data values(?, ? %s ?)";
633
        }
3307 mrmanese 634
 
3434 mrmanese 635
        /* for 2* insert statements, the values below specifies the index of bind().
636
         * if !reversed, then e1 is svec, e2 is anything. otherwise, e2 is the svec */
637
        if (reversed) { sdf_idx = 3; vec_idx = 2; }
638
        else { sdf_idx = 2; vec_idx = 3; }
3358 mrmanese 639
 
640
        if (IS_NUMERIC(op2)) {
641
            op2_len = LENGTH(op2);
642
 
643
            if (op2_len == 1) {
644
                if (funcname[0] == '%') {
645
                    sprintf(g_sql_buf[2], insert_fmt_string1c, iname, 
3434 mrmanese 646
                            (funcname[1] == '%') ? "r_mod" : "r_intdiv", varname_src, iname_src);
3358 mrmanese 647
                } else {
648
                    sprintf(g_sql_buf[2], insert_fmt_string1s, iname,
649
                            varname_src, funcname, iname_src);
650
                }
651
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
652
                _sqlite_error(res);
653
                sqlite3_bind_double(stmt, 1, REAL(op2)[0]);
654
                sqlite3_step(stmt);
3419 mrmanese 655
                sqlite3_finalize(stmt);
3358 mrmanese 656
            } else if (op2_len <= svec_len) {  /* recycle op2 */
657
                sprintf(g_sql_buf[2], "select [row name], [%s] from [%s].sdf_data",
658
                        varname_src, iname_src);
659
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt2, 0);
660
                _sqlite_error(res);
661
 
662
                if (funcname[0] == '%') {
3434 mrmanese 663
                    sprintf(g_sql_buf[2], insert_fmt_string2c, iname, 
664
                            (funcname[1] == '%') ? "r_mod" : "r_intdiv");  
3419 mrmanese 665
                    _sqlite_begin;
3358 mrmanese 666
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
667
                    _sqlite_error(res);
668
 
669
                    for (i = 0; i < svec_len; i++) {
670
                        sqlite3_step(stmt2);
671
 
672
                        sqlite3_reset(stmt);
673
                        sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
3434 mrmanese 674
                        sqlite3_bind_int(stmt, sdf_idx, (int)sqlite3_column_double(stmt2, 1));
675
                        sqlite3_bind_int(stmt, vec_idx, (int)REAL(op2)[i % op2_len]);
3358 mrmanese 676
                        sqlite3_step(stmt);
677
                    }
3419 mrmanese 678
                    sqlite3_finalize(stmt);
679
                    sqlite3_finalize(stmt2);
680
                    _sqlite_commit;
3358 mrmanese 681
                } else { /* non-integer binary operation */
682
                    sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
3419 mrmanese 683
                    _sqlite_begin;
3358 mrmanese 684
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
685
                    _sqlite_error(res);
686
 
687
                    for (i = 0; i < svec_len; i++) {
688
                        sqlite3_step(stmt2);
689
 
690
                        sqlite3_reset(stmt);
691
                        sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
3434 mrmanese 692
                        sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 1));
693
                        sqlite3_bind_double(stmt, vec_idx, REAL(op2)[i % op2_len]);
3358 mrmanese 694
                        sqlite3_step(stmt);
695
                    }
3419 mrmanese 696
                    sqlite3_finalize(stmt);
697
                    sqlite3_finalize(stmt2);
698
                    _sqlite_commit;
3358 mrmanese 699
                }
700
            } else { /* op2_len > svec_len, recycle svec */
701
                sprintf(g_sql_buf[1], "select [%s] from [%s].sdf_data",
702
                        varname_src, iname_src);
703
 
704
                if (funcname[0] == '%') {
3434 mrmanese 705
                    sprintf(g_sql_buf[2], insert_fmt_string2c, iname, 
706
                            (funcname[1] == '%') ? "r_mod" : "r_intdiv");
3358 mrmanese 707
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
708
                    _sqlite_error(res);
709
                } else {
710
                    sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
711
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
712
                    _sqlite_error(res);
713
                }
3434 mrmanese 714
 
3419 mrmanese 715
                i = 0; _sqlite_begin;
3358 mrmanese 716
                while (i < op2_len) {
717
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt2, 0);
718
                    _sqlite_error(res);
719
 
720
                    if (funcname[0] == '%') {
721
                        for ( ; i < op2_len && sqlite3_step(stmt) == SQLITE_ROW ; i++) {
722
                            sqlite3_step(stmt2);
723
 
724
                            sqlite3_reset(stmt);
725
                            /* simplify my life, just use ints for row names so that we
726
                             * don't have to worry about duplicates */
727
                            sqlite3_bind_int(stmt, 1, i); 
3434 mrmanese 728
                            sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 1));
729
                            sqlite3_bind_int(stmt, vec_idx, (int)REAL(op2)[i % op2_len]);
3358 mrmanese 730
                            sqlite3_step(stmt);
731
                        }
732
                    } else {
733
                        for ( ; i < op2_len && sqlite3_step(stmt) == SQLITE_ROW ; i++) {
734
                            sqlite3_step(stmt2);
735
 
736
                            sqlite3_reset(stmt);
737
                            sqlite3_bind_int(stmt, 1, i);
3434 mrmanese 738
                            sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 1));
739
                            sqlite3_bind_double(stmt, vec_idx, REAL(op2)[i % op2_len]);
3358 mrmanese 740
                            sqlite3_step(stmt);
741
                        }
742
                    }
743
 
744
                    /* recycle on svec if we loop again */
745
                    sqlite3_finalize(stmt2);
746
                }
3397 mrmanese 747
 
3419 mrmanese 748
                sqlite3_finalize(stmt);
749
                _sqlite_commit;
3358 mrmanese 750
            }
751
 
752
        } else if (IS_INTEGER(op2) || IS_LOGICAL(op2)) { /* I N T E G E R */
753
            /* we are taking advantage of the fact that logicals are stored as int.
754
             * if this becomes untrue in the future, then this is a bug */
3458 mrmanese 755
            /* we are binding double because ___ (?) */
3358 mrmanese 756
            op2_len = LENGTH(op2);
757
 
758
            if (op2_len == 1) {
759
                if (funcname[0] == '%') {
760
                    sprintf(g_sql_buf[2], insert_fmt_string1c, iname, 
3434 mrmanese 761
                            varname_src, (funcname[1] == '%') ? "r_mod" : "r_intdiv", iname_src);
3358 mrmanese 762
                } else {
763
                    sprintf(g_sql_buf[2], insert_fmt_string1s, iname,
764
                            varname_src, funcname, iname_src);
765
                }
766
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
767
                _sqlite_error(res);
768
                sqlite3_bind_double(stmt, 1, (double)INTEGER(op2)[0]);
769
                sqlite3_step(stmt);
770
            } else if (op2_len <= svec_len) {
771
                sprintf(g_sql_buf[2], "select [row name], [%s] from [%s].sdf_data",
772
                        varname_src, iname_src);
773
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt2, 0);
774
                _sqlite_error(res);
775
 
776
                if (funcname[0] == '%') {
3434 mrmanese 777
                    sprintf(g_sql_buf[2], insert_fmt_string2c, iname, 
778
                            (funcname[1] == '%') ? "r_mod" : "r_intdiv");
3419 mrmanese 779
                    _sqlite_begin;
3358 mrmanese 780
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
781
                    _sqlite_error(res);
782
 
783
                    for (i = 0; i < svec_len; i++) {
784
                        sqlite3_step(stmt2);
785
 
786
                        sqlite3_reset(stmt);
787
                        sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
3434 mrmanese 788
                        sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 1));
789
                        sqlite3_bind_int(stmt, vec_idx, INTEGER(op2)[i % op2_len]);
3358 mrmanese 790
                        sqlite3_step(stmt);
791
                    }
3458 mrmanese 792
                    sqlite3_finalize(stmt);
793
                    sqlite3_finalize(stmt2);
3419 mrmanese 794
                    _sqlite_commit;
3358 mrmanese 795
                } else {
796
                    sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
3419 mrmanese 797
                    _sqlite_begin;
3358 mrmanese 798
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
799
                    _sqlite_error(res);
800
 
801
                    for (i = 0; i < svec_len; i++) {
802
                        sqlite3_step(stmt2);
803
 
804
                        sqlite3_reset(stmt);
805
                        sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
3434 mrmanese 806
                        sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 1));
807
                        sqlite3_bind_double(stmt, vec_idx, (double)INTEGER(op2)[i % op2_len]);
3358 mrmanese 808
                        sqlite3_step(stmt);
809
                    }
3458 mrmanese 810
                    sqlite3_finalize(stmt);
811
                    sqlite3_finalize(stmt2);
3419 mrmanese 812
                    _sqlite_commit;
3358 mrmanese 813
                }
814
            } else {
815
                sprintf(g_sql_buf[1], "select [%s] from [%s].sdf_data",
816
                        varname_src, iname_src);
817
 
818
                if (funcname[0] == '%') {
3434 mrmanese 819
                    sprintf(g_sql_buf[2], insert_fmt_string2c, iname,
820
                            (funcname[1] == '%') ? "r_mod" : "r_intdiv");
3358 mrmanese 821
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
822
                    _sqlite_error(res);
823
                } else {
824
                    sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
825
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
826
                    _sqlite_error(res);
827
                }
828
 
3419 mrmanese 829
                i = 0; _sqlite_begin; 
3358 mrmanese 830
                while (i < op2_len) {
831
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt2, 0);
832
                    _sqlite_error(res);
833
 
834
                    if (funcname[0] == '%') {
835
                        for ( ; i < op2_len && sqlite3_step(stmt) == SQLITE_ROW ; i++) {
836
                            sqlite3_step(stmt2);
837
 
838
                            sqlite3_reset(stmt);
839
                            /* simplify my life, just use ints for row names so that we
840
                             * don't have to worry about duplicates */
841
                            sqlite3_bind_int(stmt, 1, i); 
3434 mrmanese 842
                            sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 1));
843
                            sqlite3_bind_int(stmt, vec_idx, INTEGER(op2)[i % op2_len]);
3358 mrmanese 844
                            sqlite3_step(stmt);
845
                        }
846
                    } else {
847
                        for ( ; i < op2_len && sqlite3_step(stmt) == SQLITE_ROW ; i++) {
848
                            sqlite3_step(stmt2);
849
 
850
                            sqlite3_reset(stmt);
851
                            sqlite3_bind_int(stmt, 1, i);
3434 mrmanese 852
                            sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 1));
853
                            sqlite3_bind_double(stmt, vec_idx, (double)INTEGER(op2)[i % op2_len]);
3358 mrmanese 854
                            sqlite3_step(stmt);
855
                        }
856
                    }
857
 
858
                    /* recycle on svec if we loop again */
859
                    sqlite3_finalize(stmt2);
860
                }
3458 mrmanese 861
                sqlite3_finalize(stmt);
3419 mrmanese 862
                _sqlite_commit;
3358 mrmanese 863
            }
864
 
3458 mrmanese 865
        } else if (IS_CHARACTER(op2)) {
866
            if (functype != 2) error("not supported");
867
 
868
            op2_len = LENGTH(op2);
869
 
870
            if (op2_len == 1) {
871
                sprintf(g_sql_buf[2], insert_fmt_string1s, iname,
872
                            varname_src, funcname, iname_src);
873
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
874
                _sqlite_error(res);
875
                sqlite3_bind_text(stmt, 1, CHAR_ELT(op2, 0), -1, SQLITE_STATIC);
876
                sqlite3_step(stmt);
877
            } else if (op2_len <= svec_len) {
878
                sprintf(g_sql_buf[2], "select [row name], [%s] from [%s].sdf_data",
879
                        varname_src, iname_src);
880
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt2, 0);
881
                _sqlite_error(res);
882
 
883
                sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
884
                _sqlite_begin;
885
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
886
                _sqlite_error(res);
887
 
888
                for (i = 0; i < svec_len; i++) {
889
                    sqlite3_step(stmt2);
890
 
891
                    sqlite3_reset(stmt);
892
                    sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
893
                    sqlite3_bind_text(stmt, sdf_idx, (char *)sqlite3_column_text(stmt2, 1), -1, SQLITE_STATIC);
894
                    sqlite3_bind_text(stmt, vec_idx, CHAR_ELT(op2, i % op2_len), -1 , SQLITE_STATIC);
895
                    sqlite3_step(stmt);
896
                }
897
                sqlite3_finalize(stmt2);
898
                _sqlite_commit;
899
            } else {
900
                sprintf(g_sql_buf[1], "select [%s] from [%s].sdf_data",
901
                        varname_src, iname_src);
902
 
903
                sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
904
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
905
                _sqlite_error(res);
906
 
907
                i = 0; _sqlite_begin; 
908
                while (i < op2_len) {
909
                    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt2, 0);
910
                    _sqlite_error(res);
911
 
912
                    for ( ; i < op2_len && sqlite3_step(stmt) == SQLITE_ROW ; i++) {
913
                        sqlite3_step(stmt2);
914
 
915
                        sqlite3_reset(stmt);
916
                        sqlite3_bind_int(stmt, 1, i);
917
                        sqlite3_bind_text(stmt, sdf_idx, (char *)sqlite3_column_text(stmt2, 1), -1, SQLITE_STATIC);
918
                        sqlite3_bind_text(stmt, vec_idx, CHAR_ELT(op2, i % op2_len), -1 , SQLITE_STATIC);
919
                        sqlite3_step(stmt);
920
                    }
921
 
922
                    /* recycle on svec if we loop again */
923
                    sqlite3_finalize(stmt2);
924
                }
925
                sqlite3_finalize(stmt);
926
                _sqlite_commit;
927
            }
928
 
3358 mrmanese 929
        } else if (inherits(op2, "sqlite.vector")) { 
930
            /* op2 is surely not a factor, as handled by the R wrapper */
3434 mrmanese 931
            /* even though it is impossible for reversed to be FALSE, still use
932
             * sdf_idx and vec_idx so that code would be less confusing */
3358 mrmanese 933
            char *iname_op2, *varname_op2;
934
            sqlite3_stmt *stmt3;
935
            iname_op2 = SDF_INAME(op2);
936
            varname_op2 = SVEC_VARNAME(op2);
937
 
3419 mrmanese 938
            if (!USE_SDF1(iname_op2, TRUE, TRUE)) {
3358 mrmanese 939
                /* delete created sqlite.vector */
3458 mrmanese 940
                warning("detaching created result SDF %s\n", iname);
3358 mrmanese 941
                sdf_detach_sdf(mkString(iname));
942
                return R_NilValue;
943
            }
3419 mrmanese 944
            _sqlite_begin;
3358 mrmanese 945
 
946
            op2_len = _get_row_count2(iname_op2, 1);
947
 
948
            sprintf(g_sql_buf[2], "select [%s] from [%s].sdf_data", varname_src, iname_src);
949
            res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt2, 0);
950
            _sqlite_error(res);
951
 
952
            sprintf(g_sql_buf[2], "select [%s] from [%s].sdf_data", varname_op2, iname_op2);
953
            res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt3, 0);
954
            _sqlite_error(res);
955
 
956
            if (funcname[0] == '%') {
3434 mrmanese 957
                sprintf(g_sql_buf[2], insert_fmt_string2c, iname,
958
                            (funcname[1] == '%') ? "r_mod" : "r_intdiv");
3358 mrmanese 959
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
960
                _sqlite_error(res);
961
 
962
                if (svec_len == op2_len) {
963
                    for (i = 0; i < svec_len; i++) {
964
                        sqlite3_step(stmt2); sqlite3_step(stmt3);
965
 
966
                        sqlite3_reset(stmt);
967
                        sqlite3_bind_int(stmt, 1, i);
3434 mrmanese 968
                        sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 0));
969
                        sqlite3_bind_int(stmt, vec_idx, sqlite3_column_int(stmt3, 0));
3358 mrmanese 970
                        sqlite3_step(stmt);
971
                    }
972
                } else if (svec_len < op2_len) {
973
                    i = 0;
974
                    while (i < op2_len) {
975
                        for ( ; sqlite3_step(stmt2) == SQLITE_ROW && i < op2_len; i++) {
976
                            sqlite3_step(stmt3);
977
 
978
                            sqlite3_reset(stmt);
979
                            sqlite3_bind_int(stmt, 1, i);
3434 mrmanese 980
                            sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 0));
981
                            sqlite3_bind_int(stmt, vec_idx, sqlite3_column_int(stmt3, 0));
3358 mrmanese 982
                            sqlite3_step(stmt);
983
                        }
984
                        sqlite3_reset(stmt2);
985
                    }
986
                } else {
987
                    i = 0;
988
                    while (i < svec_len) {
989
                        for ( ; sqlite3_step(stmt3) == SQLITE_ROW && i < svec_len; i++) {
990
                            sqlite3_step(stmt2);
991
 
992
                            sqlite3_reset(stmt);
993
                            sqlite3_bind_int(stmt, 1, i);
3434 mrmanese 994
                            sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 0));
995
                            sqlite3_bind_int(stmt, vec_idx, sqlite3_column_int(stmt3, 0));
3358 mrmanese 996
                            sqlite3_step(stmt);
997
                        }
998
                        sqlite3_reset(stmt3);
999
                    }
1000
                }
3419 mrmanese 1001
                _sqlite_commit;
3358 mrmanese 1002
            } else { /* not an integer op %% or %/% */
1003
                sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
1004
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
1005
                _sqlite_error(res);
1006
 
1007
                if (svec_len == op2_len) {
1008
                    for (i = 0; i < svec_len; i++) {
1009
                        sqlite3_step(stmt2); sqlite3_step(stmt3);
1010
 
1011
                        sqlite3_reset(stmt);
1012
                        sqlite3_bind_int(stmt, 1, i);
3434 mrmanese 1013
                        sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 0));
1014
                        sqlite3_bind_double(stmt, vec_idx, sqlite3_column_double(stmt3, 0));
3358 mrmanese 1015
                        sqlite3_step(stmt);
1016
                    }
1017
                } else if (svec_len < op2_len) { /* recycle svec */
1018
                    i = 0;
1019
                    while (i < op2_len) {
1020
                        for ( ; sqlite3_step(stmt2) == SQLITE_ROW && i < op2_len; i++) {
1021
                            sqlite3_step(stmt3);
1022
 
1023
                            sqlite3_reset(stmt);
1024
                            sqlite3_bind_int(stmt, 1, i);
3434 mrmanese 1025
                            sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 0));
1026
                            sqlite3_bind_double(stmt, vec_idx, sqlite3_column_double(stmt3, 0));
3358 mrmanese 1027
                            sqlite3_step(stmt);
1028
                        }
1029
                        sqlite3_reset(stmt2);
1030
                    }
1031
                } else { /* svec_len > op2_len, recycle op2 */
1032
                    i = 0;
1033
                    while (i < svec_len) {
1034
                        for ( ; sqlite3_step(stmt3) == SQLITE_ROW && i < svec_len; i++) {
1035
                            sqlite3_step(stmt2);
1036
 
1037
                            sqlite3_reset(stmt);
1038
                            sqlite3_bind_int(stmt, 1, i);
3434 mrmanese 1039
                            sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 0));
1040
                            sqlite3_bind_double(stmt, vec_idx, sqlite3_column_double(stmt3, 0));
3358 mrmanese 1041
                            sqlite3_step(stmt);
1042
                        }
1043
                        sqlite3_reset(stmt3);
1044
                    }
1045
                }
1046
            }
1047
 
1048
            sqlite3_finalize(stmt);
1049
            sqlite3_finalize(stmt2);
1050
            sqlite3_finalize(stmt3);
3419 mrmanese 1051
            _sqlite_commit;
1052
 
1053
            UNUSE_SDF2(iname_op2);
3358 mrmanese 1054
        }
1055
    } else if (functype == 1 && funcname[0] != '!') { /* unary not operator */
3419 mrmanese 1056
        iname = _create_svector1(R_NilValue, "bit", NULL, TRUE);
3358 mrmanese 1057
        sprintf(g_sql_buf[2], "insert into [%s].sdf_data "
1058
                    "select [row name], [%s] == 0 from [%s].sdf_data", 
1059
                    iname, varname_src, iname_src);
1060
        res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
1061
        _sqlite_error(res);
1062
        sqlite3_step(stmt);
1063
        sqlite3_finalize(stmt);
1064
    }
1065
 
3419 mrmanese 1066
    if (iname != NULL) {
3684 mrmanese 1067
        return _create_svector_sexp(iname, "sdf_data", "V1", 
3358 mrmanese 1068
                (functype == 0) ? "numeric" : "logical");
3419 mrmanese 1069
        UNUSE_SDF2(iname);
1070
    }
3358 mrmanese 1071
 
3419 mrmanese 1072
    UNUSE_SDF2(iname_src);
1073
 
3358 mrmanese 1074
    return R_NilValue;
1075
 
3307 mrmanese 1076
}
1077
 
3324 mrmanese 1078
SEXP sdf_do_variable_summary(SEXP func, SEXP vector, SEXP na_rm) {
1079
    char *iname_src, *varname_src, *funcname;
1080
    int res;
1081
    sqlite3_stmt *stmt;
3855 mrmanese 1082
    double _ret = NA_REAL, _ret2; SEXP ret;
3307 mrmanese 1083
 
3324 mrmanese 1084
    /* get data from arguments (function name and sqlite.vector stuffs) */
1085
    funcname = CHAR_ELT(func, 0);
1086
    iname_src = SDF_INAME(vector);
1087
    varname_src = SVEC_VARNAME(vector);
3307 mrmanese 1088
 
3419 mrmanese 1089
    if (!USE_SDF1(iname_src, TRUE, FALSE)) return R_NilValue;
3324 mrmanese 1090
 
1091
    g_narm = LOGICAL(na_rm)[0];
1092
    if (strcmp(funcname, "range") == 0) {
1093
        /* special handling for range. use min then max */
3473 mrmanese 1094
        _init_sqlite_function_accumulator();
3324 mrmanese 1095
        sprintf(g_sql_buf[0], "select min_df([%s]) from [%s].sdf_data", varname_src, iname_src);
1096
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
1097
        if (_sqlite_error(res)) return R_NilValue;
3855 mrmanese 1098
        sqlite3_step(stmt); 
1099
        _ret = sqlite3_column_double(stmt, 0);
1100
        sqlite3_finalize(stmt);
3324 mrmanese 1101
 
1102
        if (R_IsNA(_ret) && !g_narm) {
1103
            PROTECT(ret = NEW_NUMERIC(2));
1104
            REAL(ret)[0] = REAL(ret)[1] = R_NaReal;
1105
            goto __sdf_do_variable_summary_out;
1106
        }
1107
 
3473 mrmanese 1108
        _init_sqlite_function_accumulator();
3324 mrmanese 1109
        sprintf(g_sql_buf[0], "select max_df([%s]) from [%s].sdf_data", varname_src, iname_src);
1110
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
1111
        if (_sqlite_error(res)) return R_NilValue;
3855 mrmanese 1112
        sqlite3_step(stmt); 
1113
        _ret2 = sqlite3_column_double(stmt, 0);
1114
        sqlite3_finalize(stmt);
3324 mrmanese 1115
 
1116
        /* if there is NA, then the if above should have caught it already */
1117
        PROTECT(ret = NEW_NUMERIC(2));
1118
        REAL(ret)[0] = _ret;
3855 mrmanese 1119
        REAL(ret)[1] = _ret2;
3324 mrmanese 1120
    } else {
3473 mrmanese 1121
        _init_sqlite_function_accumulator();
3324 mrmanese 1122
        sprintf(g_sql_buf[0], "select %s_df([%s]) from [%s].sdf_data", funcname, varname_src, iname_src);
1123
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
1124
        if (_sqlite_error(res)) return R_NilValue;
3855 mrmanese 1125
        res = sqlite3_step(stmt); 
1126
        _ret = sqlite3_column_double(stmt, 0);
1127
        sqlite3_finalize(stmt);
3324 mrmanese 1128
 
1129
        if (strcmp(funcname, "all") == 0 || strcmp(funcname, "any") == 0) {
1130
            PROTECT(ret = NEW_LOGICAL(1));
3855 mrmanese 1131
            if (R_IsNA(_ret)) LOGICAL(ret)[0] = NA_INTEGER;
1132
            else LOGICAL(ret)[0] = (_ret != 0);
3324 mrmanese 1133
        } else {
1134
            PROTECT(ret = NEW_NUMERIC(1));
3855 mrmanese 1135
            REAL(ret)[0] = _ret;
3324 mrmanese 1136
        }
1137
    }
1138
 
1139
__sdf_do_variable_summary_out:
1140
    UNPROTECT(1);
1141
    return ret;
1142
}
1143
 
1144
 
3358 mrmanese 1145
SEXP sdf_sort_variable(SEXP svec, SEXP decreasing) {
4160 mrmanese 1146
    char *iname, *tblname, *varname, *type, *sort_type;
3358 mrmanese 1147
    sqlite3_stmt *stmt;
1148
    int res;
1149
 
3808 mrmanese 1150
    iname = SDF_INAME(svec);
1151
    tblname = SVEC_TBLNAME(svec);
1152
    varname = SVEC_VARNAME(svec);
3358 mrmanese 1153
 
3808 mrmanese 1154
    if (!USE_SDF1(iname, TRUE, TRUE)) return R_NilValue;
3358 mrmanese 1155
 
1156
    /* determine type of svec */
3808 mrmanese 1157
    sprintf(g_sql_buf[0], "select [%s] from [%s].[%s] limit 1", varname, iname, tblname);
3358 mrmanese 1158
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
1159
    _sqlite_error(res);
1160
    sqlite3_step(stmt);
1161
    strcpy(g_sql_buf[0], sqlite3_column_decltype(stmt, 0));
1162
    sqlite3_finalize(stmt);
1163
 
3456 mrmanese 1164
    if (TEST_SDFVECTORTYPE(svec, "factor")) { /* copy factor table to iname */
1165
        if (TEST_SDFVECTORTYPE(svec, "ordered")) type = "ordered";
3358 mrmanese 1166
        else type = "factor";
3808 mrmanese 1167
        _copy_factor_levels2(type, iname, varname, iname, "V1");
3471 mrmanese 1168
    } else type = CHAR_ELT(GET_SDFVECTORTYPE(svec), 0);
3358 mrmanese 1169
 
3808 mrmanese 1170
    if (strcmp(tblname, "sdf_data") == 0) {
1171
        /* cache sorted data if column to be sorted comes from main sdf_data */
3419 mrmanese 1172
 
3808 mrmanese 1173
        /* test if there is already a sort_varname table */
1174
        sort_type = (LOGICAL(decreasing)[0]) ? "desc" : "asc";
1175
        sprintf(g_sql_buf[1], "select count(*) from [%s].sqlite_master "
1176
                "where type='table' and name='sort_%s_%s'", iname, sort_type, varname);
1177
        sqlite3_prepare(g_workspace, g_sql_buf[1], -1, &stmt, NULL);
1178
        sqlite3_step(stmt);
1179
        res = sqlite3_column_int(stmt, 0);
1180
        sqlite3_finalize(stmt);
1181
 
1182
        if (res == 0) {
1183
            sprintf(g_sql_buf[1], "create table [%s].[sort_%s_%s] ([%s] %s)", 
1184
                    iname, sort_type, varname, varname, g_sql_buf[0]);
1185
            if (_sqlite_error(_sqlite_exec(g_sql_buf[1]))) 
1186
                    error("Can't create table: %s", g_sql_buf[1]);
1187
 
1188
            /* insert to new sdf ordered */
1189
            sprintf(g_sql_buf[0], "insert into [%s].[sort_%s_%s] "
1190
                    "select [%s] from [%s].[%s] order by [%s] %s", 
1191
                    iname, sort_type, varname, varname, iname, tblname, varname, sort_type);
1192
 
1193
            res = _sqlite_exec(g_sql_buf[0]);
1194
            if (_sqlite_error(res)) error("Can't insert: %s", g_sql_buf[0]);
1195
        }
1196
 
1197
        UNUSE_SDF2(iname);
1198
        sprintf(g_sql_buf[0], "sort_%s_%s", sort_type, varname);
1199
        return _create_svector_sexp(iname, g_sql_buf[0], varname, type);
1200
    } else {
1201
        /* create a new sdf table, copy data to that */
1202
 
1203
        /* create a sorted column */
1204
 
1205
        error("Not yet supported.");
1206
    }
1207
 
1208
    return R_NilValue;
3358 mrmanese 1209
}
1210
 
3307 mrmanese 1211
/****************************************************************************
1212
 * VECTOR MATH/OPS/GROUP OPERATIONS
1213
 ****************************************************************************/
3855 mrmanese 1214
struct accumulator_t {
1215
    /* long double acts weird here, but if it's not long double,
1216
     * it f*cks up sum() */
1217
    long double accumulator;
1218
    int started;
1219
};
3324 mrmanese 1220
 
3434 mrmanese 1221
R_INLINE int __vecmath_checkarg(sqlite3_context *ctx, sqlite3_value *arg, double *value) {
3307 mrmanese 1222
    int ret = 1;
1223
    if (sqlite3_value_type(arg) == SQLITE_NULL) { 
1224
        sqlite3_result_null(ctx); 
1225
        ret = 0;
1226
    } else {
1227
        if (sqlite3_value_type(arg) == SQLITE_INTEGER) 
1228
            *value = sqlite3_value_int(arg); 
1229
        else *value = sqlite3_value_double(arg); 
1230
    }
1231
    return ret;
1232
}
1233
 
1234
#define SQLITE_MATH_FUNC1(name, func) static void __vecmath_ ## name(\
1235
        sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
1236
    double value; \
1237
    if (__vecmath_checkarg(ctx, argv[0], &value)) { \
1238
        sqlite3_result_double(ctx, func(value)); \
1239
    }  \
1240
}
1241
 
3434 mrmanese 1242
#define SQLITE_MATH_FUNC2(name, func) static void __vecmath_ ## name(\
1243
        sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
1244
    double value1, value2; \
1245
    if (__vecmath_checkarg(ctx, argv[0], &value1) && \
1246
        __vecmath_checkarg(ctx, argv[1], &value2)) { \
1247
        sqlite3_result_double(ctx, func((long double)value1, (long double)value2)); \
1248
    }  \
1249
}
1250
 
3324 mrmanese 1251
#define SQLITE_MATH_FUNC_CUM(name, func) static void __vecmath_ ## name(\
1252
        sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
1253
    double value; \
1254
    if (__vecmath_checkarg(ctx, argv[0], &value)) { \
1255
        if (g_start) { g_start = 0; g_accumulator = value; } \
1256
        else g_accumulator = func(g_accumulator, value); \
1257
        sqlite3_result_double(ctx, g_accumulator); \
1258
    }  \
1259
}
1260
 
3434 mrmanese 1261
#define LOGBASE(a, b) log(a)/log(b)
1262
 
3307 mrmanese 1263
/* SQLITE_MATH_FUNC1(abs, abs)   in SQLite */
1264
SQLITE_MATH_FUNC1(sign, sign)   /* in R */
1265
SQLITE_MATH_FUNC1(sqrt, sqrt)
1266
SQLITE_MATH_FUNC1(floor, floor)
1267
SQLITE_MATH_FUNC1(ceiling, ceil)
1268
SQLITE_MATH_FUNC1(trunc, ftrunc) /* in R */
3434 mrmanese 1269
/*SQLITE_MATH_FUNC2(round, fprec)  2 arg, in SQLite, but override with R's version */
1270
SQLITE_MATH_FUNC2(signif, fround) /* 2 arg, in R */
3307 mrmanese 1271
SQLITE_MATH_FUNC1(exp, exp)
3434 mrmanese 1272
SQLITE_MATH_FUNC2(log, LOGBASE) /* 2 arg */
3307 mrmanese 1273
SQLITE_MATH_FUNC1(cos, cos)
1274
SQLITE_MATH_FUNC1(sin, sin)
1275
SQLITE_MATH_FUNC1(tan, tan)
1276
SQLITE_MATH_FUNC1(acos, acos)
1277
SQLITE_MATH_FUNC1(asin, asin)
1278
SQLITE_MATH_FUNC1(atan, atan)
1279
SQLITE_MATH_FUNC1(cosh, cosh)
1280
SQLITE_MATH_FUNC1(sinh, sinh)
1281
SQLITE_MATH_FUNC1(tanh, tanh)
1282
SQLITE_MATH_FUNC1(acosh, acosh)  /* nowhere in include?? */
1283
SQLITE_MATH_FUNC1(asinh, asinh)  /* nowhere in include?? */
1284
SQLITE_MATH_FUNC1(atanh, atanh)  /* nowhere in include?? */
1285
SQLITE_MATH_FUNC1(lgamma, lgammafn) /* in R */
1286
SQLITE_MATH_FUNC1(gamma, gammafn) /* in R */
1287
/* SQLITE_MATH_FUNC1(gammaCody, gammaCody)   * in R ?? */
1288
SQLITE_MATH_FUNC1(digamma, digamma) /* in R */    
1289
SQLITE_MATH_FUNC1(trigamma, trigamma) /* in R */
1290
 
3855 mrmanese 1291
#define SUM(a, b)  ((long double)(a) + (b))
3324 mrmanese 1292
#define PROD(a, b) (a) * (b)
1293
#define MIN(a, b) ((a) <= (b)) ? (a) : (b)
1294
#define MAX(a, b) ((a) >= (b)) ? (a) : (b)
1295
#define ALL(a, b) (((a) == 0) || ((b) == 0)) ? 0 : 1
1296
#define ANY(a, b) (((a) == 0) && ((b) == 0)) ? 0 : 1
1297
 
1298
SQLITE_MATH_FUNC_CUM(cumsum, SUM)
1299
SQLITE_MATH_FUNC_CUM(cumprod, PROD)
1300
SQLITE_MATH_FUNC_CUM(cummin, MIN)
1301
SQLITE_MATH_FUNC_CUM(cummax, MAX)
1302
 
1303
#define SQLITE_SUMMARY_FUNC(name, func) static void __vecsummary_ ## name(\
1304
        sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
1305
    double value; \
3855 mrmanese 1306
    struct accumulator_t *acc; \
1307
    acc = sqlite3_aggregate_context(ctx, sizeof(struct accumulator_t)); \
1308
    if (!g_narm && R_IsNA(acc->accumulator)) return; /* NA if na.rm=F & NA found */ \
3324 mrmanese 1309
    if (sqlite3_value_type(argv[0]) != SQLITE_NULL) {  \
1310
        if (sqlite3_value_type(argv[0]) == SQLITE_INTEGER) {  \
1311
            int tmp = sqlite3_value_int(argv[0]); \
1312
            value = (tmp == NA_INTEGER) ? R_NaReal : tmp; \
1313
        } else value = sqlite3_value_double(argv[0]);  \
1314
        if (R_IsNA(value)) { \
3855 mrmanese 1315
            if (!g_narm) acc->accumulator = value; return; /* else ignore */ \
1316
        } else if (!acc->started) { \
1317
            acc->started = 1; \
1318
            acc->accumulator = value; \
1319
        } else acc->accumulator = func(acc->accumulator, value); \
3324 mrmanese 1320
    } \
1321
}
1322
 
1323
SQLITE_SUMMARY_FUNC(all_df, ALL)
1324
SQLITE_SUMMARY_FUNC(any_df, ANY)
1325
SQLITE_SUMMARY_FUNC(sum_df, SUM)
1326
SQLITE_SUMMARY_FUNC(prod_df, PROD)
1327
SQLITE_SUMMARY_FUNC(min_df, MIN)
1328
SQLITE_SUMMARY_FUNC(max_df, MAX)
1329
 
1330
static void __vecsummary_finalize(sqlite3_context *ctx) {
1331
    /* g_accumulator already summarizes it. just return that */
3855 mrmanese 1332
    struct accumulator_t *acc = (struct accumulator_t *)
1333
                sqlite3_aggregate_context(ctx, sizeof(struct accumulator_t)); 
1334
    sqlite3_result_double(ctx, acc->accumulator);
3324 mrmanese 1335
}
1336
 
3434 mrmanese 1337
static void __r_modulo(sqlite3_context *ctx, int argc, sqlite3_value **argv) {
1338
    if (sqlite3_value_type(argv[0]) == SQLITE_NULL ||
1339
        sqlite3_value_type(argv[1]) == SQLITE_NULL) { 
1340
        sqlite3_result_null(ctx); 
1341
    } else {
1342
        double v1, v2, q, tmp;
1343
        if (sqlite3_value_type(argv[0]) == SQLITE_INTEGER && 
1344
            sqlite3_value_type(argv[1]) == SQLITE_INTEGER) {
1345
            int i1, i2;
1346
            i1 = sqlite3_value_int(argv[0]);
1347
            i2 = sqlite3_value_int(argv[1]);
1348
            if (i1 > 0 && i2 > 0) { 
1349
                sqlite3_result_int(ctx, i1 % i2); return;
1350
            }
1351
            v1 = i1; v2 = i2;
1352
        } else {
1353
            v1 = sqlite3_value_double(argv[0]);
1354
            v2 = sqlite3_value_double(argv[1]);
1355
        }
1356
        /* copied from myfmod() in src/main/arithmetic.c */
1357
        q = v1 / v2; 
1358
        if (v2 == 0) sqlite3_result_double(ctx, R_NaN);
1359
        tmp = v1 - floor(q) * v2;
1360
        /* checking omitted */
1361
        q = floor(tmp/v2);
1362
        sqlite3_result_double(ctx, tmp - q*v2);
1363
 
1364
    }
1365
}
1366
 
1367
static void __r_intdiv(sqlite3_context *ctx, int argc, sqlite3_value **argv) {
1368
    if (sqlite3_value_type(argv[0]) == SQLITE_NULL ||
1369
        sqlite3_value_type(argv[1]) == SQLITE_NULL) { 
1370
        sqlite3_result_null(ctx); 
1371
    } else {
1372
        double v1, v2;
1373
        if (sqlite3_value_type(argv[0]) == SQLITE_INTEGER && 
1374
            sqlite3_value_type(argv[1]) == SQLITE_INTEGER) {
1375
            int i1, i2;
1376
            i1 = sqlite3_value_int(argv[0]);
1377
            i2 = sqlite3_value_int(argv[1]);
1378
            if (i1 == NA_INTEGER || i2 == NA_INTEGER) {
1379
                sqlite3_result_int(ctx, NA_INTEGER); return;
1380
            } else if (i2 == 0) {
1381
                sqlite3_result_int(ctx, 0); return;
1382
            }
1383
            v1 = i1; v2 = i2;
1384
        } else {
1385
            v1 = sqlite3_value_double(argv[0]);
1386
            v2 = sqlite3_value_double(argv[1]);
1387
        }
1388
        /* copied from IDIVOP cases in src/main/arithmetic.c */
1389
        sqlite3_result_double(ctx, floor(v1/v2));
1390
    }
1391
}
3307 mrmanese 1392
#define VMENTRY1(func)  {#func, __vecmath_ ## func}
3324 mrmanese 1393
#define VSENTRY1(func)  {#func, __vecsummary_ ## func}
3307 mrmanese 1394
void __register_vector_math() {
1395
    int i, res;
1396
    static const struct {
1397
        char *name;
1398
        void (*func)(sqlite3_context*, int, sqlite3_value**);
1399
    } arr_func1[] = {
1400
        VMENTRY1(sign),
1401
        VMENTRY1(sqrt),
1402
        VMENTRY1(floor),
1403
        VMENTRY1(ceiling),
1404
        VMENTRY1(trunc),
1405
        VMENTRY1(exp),
1406
        VMENTRY1(cos),
1407
        VMENTRY1(sin),
1408
        VMENTRY1(tan),
1409
        VMENTRY1(acos),
1410
        VMENTRY1(asin),
1411
        VMENTRY1(atan),
1412
        VMENTRY1(cosh),
1413
        VMENTRY1(sinh),
1414
        VMENTRY1(tanh),
1415
        VMENTRY1(acosh),
1416
        VMENTRY1(asinh),
1417
        VMENTRY1(atanh),
1418
        VMENTRY1(lgamma),
1419
        VMENTRY1(gamma),
1420
        VMENTRY1(digamma),
3324 mrmanese 1421
        VMENTRY1(trigamma),
1422
        VMENTRY1(cumsum),
1423
        VMENTRY1(cumprod),
1424
        VMENTRY1(cummin),
1425
        VMENTRY1(cummax)
3434 mrmanese 1426
    }, arr_func2[] =  {
1427
        {"r_mod", __r_modulo},
1428
        {"r_intdiv", __r_intdiv},
1429
        /*VMENTRY1(round),*/
1430
        VMENTRY1(signif),
1431
        VMENTRY1(log)
3324 mrmanese 1432
    }, arr_sum1[] = {
1433
        VSENTRY1(all_df),  /* can't override sum, min, max */
1434
        VSENTRY1(any_df),
1435
        VSENTRY1(sum_df),
1436
        VSENTRY1(prod_df),
1437
        VSENTRY1(min_df),
1438
        VSENTRY1(max_df)
3307 mrmanese 1439
    };
1440
 
3324 mrmanese 1441
    int len = sizeof(arr_func1) / sizeof(arr_func1[0]);
3307 mrmanese 1442
 
3324 mrmanese 1443
    for (i = 0; i < len; i++) {
3307 mrmanese 1444
        res = sqlite3_create_function(g_workspace, arr_func1[i].name, 1, 
1445
                SQLITE_ANY, NULL, arr_func1[i].func, NULL, NULL);
1446
        _sqlite_error(res);
1447
    }
3324 mrmanese 1448
 
3434 mrmanese 1449
    len = sizeof(arr_func2) / sizeof(arr_func2[0]);
1450
    for (i = 0; i < len; i++) {
1451
        res = sqlite3_create_function(g_workspace, arr_func2[i].name, 2, 
1452
                SQLITE_ANY, NULL, arr_func2[i].func, NULL, NULL);
1453
        _sqlite_error(res);
1454
    }
1455
 
3324 mrmanese 1456
    len = sizeof(arr_sum1) / sizeof(arr_sum1[0]);
1457
    for (i = 0; i < len; i++) {
1458
        res = sqlite3_create_function(g_workspace, arr_sum1[i].name, 1, 
1459
                SQLITE_ANY, NULL, NULL, arr_sum1[i].func, __vecsummary_finalize);
1460
        _sqlite_error(res);
1461
    }
3307 mrmanese 1462
}