Hi there,
When we use our custom SQLite function function_sparql_regex (lower in
this E-mail) together with bound values for the argvs of the function,
then sqlite3_reset nor sqlite3_clear_bindings are clearning the auxdata.
This makes it impossible to pass the regex as a sqlite3_bind_text (the
same regex would be used even if you'd pass a new regex string).
The sqlite3_set_auxdata's destroy function ptr is called when you'd
sqlite3_finalize the stmt each time, of course. But then it's not
possible to cache our statements as efficiently as we are doing right
now.
Here's an example that reproduces it:
static sqlite *db = NULL;
static const *filename = "test.db";
static sqlite3_stmt *stmt = NULL;
static void
open_db (void)
{
sqlite3_open (filename, &db) != SQLITE_OK);
sqlite3_create_function (db, "SparqlRegex", 3, SQLITE_ANY,
priv, &function_sparql_regex,
NULL, NULL);
}
static void
exec_regex (char *regex, char *mod)
{
if (!stmt) {
sqlite3_prepare_v2 (db, "SELECT field FROM Table"
"WHERE ... AND ... "
"SparqlRegex (field, ?, ?)",
-1, &stmt, NULL);
} else {
sqlite3_reset (stmt);
sqlite3_clear_bindings (stmt);
}
sqlite3_bind_text (stmt, 0, regex, -1, SQLITE_TRANSIENT);
sqlite3_bind_text (stmt, 1, mod, -1, SQLITE_TRANSIENT);
...
sqlite3_step () ...
...
}
static void
app (void)
{
open_db ();
exec_regex (".*", "i");
exec_regex ("foo", "i");
}
-----
static void
function_sparql_regex (sqlite3_context *context,
int argc,
sqlite3_value *argv[])
{
gboolean ret;
const gchar *text, *pattern, *flags;
GRegexCompileFlags regex_flags;
GRegex *regex;
if (argc != 3) {
sqlite3_result_error (context, “Invalid argument count”, -1);
return;
}
regex = sqlite3_get_auxdata (context, 1);
text = sqlite3_value_text (argv[0]);
flags = sqlite3_value_text (argv[2]);
if (regex == NULL) {
gchar *err_str;
GError *error = NULL;
pattern = sqlite3_value_text (argv[1]);
regex_flags = 0;
while (*flags) {
switch (*flags) {
case ’s’: regex_flags |= G_REGEX_DOTALL; break;
case ‘m’: regex_flags |= G_REGEX_MULTILINE; break;
case ‘i’: regex_flags |= G_REGEX_CASELESS; break;
case ‘x’: regex_flags |= G_REGEX_EXTENDED; break;
default:
err_str = g_strdup_printf (”Invalid SPARQL regex flag ‘%c’”, *flags);
sqlite3_result_error (context, err_str, -1);
g_free (err_str);
return;
}
flags++;
}
regex = g_regex_new (pattern, regex_flags, 0, &error);
if (error) {
sqlite3_result_error (context, error->message, error->code);
g_clear_error (&error);
return;
}
sqlite3_set_auxdata (context, 1, regex, (void (*) (void*)) g_regex_unref);
}
ret = g_regex_match (regex, text, 0, NULL);
sqlite3_result_int (context, ret);
return;
}
--
Philip Van Hoof
freelance software developer
Codeminded BVBA - http://codeminded.be
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users