The R Project SVN R-packages

Rev

Rev 3308 | Rev 3358 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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