The R Project SVN R-packages

Rev

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