Hi,
forget to mention that a function like this was earlier considered as
being tricky and living dangerously.
Also we found a bug (missing break) between line 80 and 81 which will
lead to a memory leak every time a text value is stored ...
switch (pval->t) {
case SQLITE_INTEGER:
pval->n=0;
pval->i=sqlite3_value_int64(arg);
break;
case SQLITE_TEXT:
pval->n=sqlite3_value_bytes(arg);
if (!pval->n) {
pval->z="";
} else {
pval->z=sqlite3_malloc(pval->n);
assert (pval->z); /* TODO: SQLITE_NOMEM*/
memcpy(pval->z,sqlite3_value_text(arg),pval->n);
}
break; /* <<<<<<<<<< MISSING break <<<<<<<<<< */
case SQLITE_BLOB: /* sqlite3_value_blob instead of _text */
pval->n=sqlite3_value_bytes(arg);
if (!pval->n) {
pval->z="";
} else {
pval->z=sqlite3_malloc(pval->n);
assert (pval->z); /* TODO: SQLITE_NOMEM*/
memcpy(pval->z,sqlite3_value_blob(arg),pval->n);
}
break;
case SQLITE_FLOAT:
pval->n=0;
pval->r=sqlite3_value_double(arg);
break;
}
}
I reproduced the memory leak and added a test in the sql script.
An alternative fix, instead of adding the missing break, is:
case SQLITE_TEXT:
case SQLITE_BLOB:
pval->n=sqlite3_value_bytes(arg);
if (!pval->n) {
pval->z="";
} else {
pval->z=sqlite3_malloc(pval->n);
assert (pval->z); /* TODO: SQLITE_NOMEM*/
memcpy(pval->z,sqlite3_value_blob(arg),pval->n);
}
break;
Thus sqlite3_value_blob is used to get both text or blob value (like
in sqlite3.c at line ~93615 in routine attachFunc).
If no response I opt for the alternative fix and place it at
http://h1972688.stratoserver.net/sqlite_mprint/160223
E. Pasma