Yes, you are right. Thanks for the investigation.
On Sun, Feb 9, 2014 at 11:54 PM, Richard Hipp <d...@sqlite.org> wrote: > This behavior change is in response to ticket > http://www.sqlite.org/src/info/406d3b2ef9 - a diff across several check-ins > that makes this change can be seen here: > > > http://www.sqlite.org/src/vdiff?from=b1b0de29fdf7de83&to=62465ecba7431e1d&sbs=1&dc=25 > > Note that the behavior changes brings the implementation into agreement > with the historical documentation. The document was clarified and enhanced > as part of this change. But the key statements in the old documentation > where: > > "If [the sqlite3_set_auxdata destructor] is not NULL, SQLite will invoke > the destructor function given by the 4th parameter to sqlite3_set_auxdata() > on the metadata when the corresponding function parameter changes or when > the SQL statement completes, whichever comes first. SQLite is free to call > the destructor and drop metadata on any parameter of any function at any > time. The only guarantee is that the destructor will be called before the > metadata is dropped." > > The corresponding text in the revised documentation is similar: > > "SQLite is free to discard the metadata at any time, including: > * when the corresponding function parameter changes, or > * when [sqlite3_reset()] or [sqlite3_finalize()] is called for the SQL > statement, or > * when sqlite3_set_auxdata() is invoked again on the same parameter, or > * during the original sqlite3_set_auxdata() call when a memory > allocation error occurs. " > > The revised documentation is on the website here: > http://www.sqlite.org/c3ref/get_auxdata.html > > So as far as I can tell, the current implementation is doing what it is > suppose to do. Or did I misunderstand the complaint? > > > > > > On Sun, Feb 9, 2014 at 10:50 AM, gwenn <gwenn.k...@gmail.com> wrote: > >> Hello, >> I am not sure but it seems there is a regression between versions >> 3.7.17 and 3.8.0. >> It's impacting custom/user declared function and auxiliary data. >> >> sqlite-amalgamation-3071700 gwen$ gcc >> -I/usr/local/Cellar/glib/2.38.2/include/glib-2.0 >> -I/usr/local/Cellar/glib/2.38.2/lib/glib-2.0/include sqlite3.c >> auxdata.c -o auxdata -L/usr/local/Cellar/glib/2.38.2/lib -lglib-2.0 >> sqlite-amalgamation-3071700 gwen$ ./auxdata >> loop 1 >> (0) compiling... >> zzzzz >> (0) reusing... >> yyyyy >> loop 2 >> (0) reusing... >> zzzzz >> (0) reusing... >> yyyyy >> >> sqlite-amalgamation-3080300 gwen$ gcc >> -I/usr/local/Cellar/glib/2.38.2/include/glib-2.0 >> -I/usr/local/Cellar/glib/2.38.2/lib/glib-2.0/include sqlite3.c >> auxdata.c -o auxdata -L/usr/local/Cellar/glib/2.38.2/lib -lglib-2.0 >> sqlite-amalgamation-3080300 gwen$ ./auxdata >> loop 1 >> (0) compiling... >> zzzzz >> (0) reusing... >> yyyyy >> loop 2 >> (0) compiling... >> zzzzz >> (0) reusing... >> yyyyy >> >> The auxiliary data is reused in the second loop with SQLite 3.7.17 but >> not with SQLite 3.8.0. >> What is the expected/correct behaviour? >> >> Regards >> >> Here is the content of auxdata.c: >> #include <stdlib.h> >> #include <stdio.h> >> #include <glib.h> >> #include "sqlite3.h" >> >> static void log(void *pArg, int iErrCode, const char *zMsg) { >> printf("(%d) %s\n", iErrCode, zMsg); >> } >> >> static void glibRegexpDelete(void *p){ >> GRegex *pRegex = (GRegex *)p; >> g_regex_unref(pRegex); >> } >> >> static void glibReplaceAllFunc( >> sqlite3_context *ctx, >> int argc, >> sqlite3_value **argv >> ){ >> GError *err = NULL; >> GRegex *p; >> gchar *result = NULL; >> >> (void)argc; /* Unused parameter */ >> >> const gchar *str = (const gchar *) sqlite3_value_text(argv[1]); >> if (!str) { >> return; >> } >> >> const gchar *replacement = (const gchar *) sqlite3_value_text(argv[2]); >> if (!replacement) { >> sqlite3_result_error(ctx, "no replacement string", -1); >> return; >> } >> >> p = sqlite3_get_auxdata(ctx, 0); >> if( !p ){ >> const gchar *re = (const gchar *) sqlite3_value_text(argv[0]); >> if( !re ){ >> //sqlite3_result_error(ctx, "no regexp", -1); >> return; >> } >> p = g_regex_new(re, 0, 0, &err); >> >> if( p ){ >> sqlite3_set_auxdata(ctx, 0, p, glibRegexpDelete); >> }else{ >> char *e2 = sqlite3_mprintf("%s: %s", re, err->message); >> sqlite3_result_error(ctx, e2, -1); >> sqlite3_free(e2); >> g_error_free(err); >> return; >> } >> sqlite3_log(0, "compiling..."); >> } else { >> sqlite3_log(0, "reusing..."); >> } >> >> result = g_regex_replace(p, str, -1, 0, replacement, 0, &err); >> if (err) { >> sqlite3_result_error(ctx, err->message, -1); >> g_error_free(err); >> return; >> } >> sqlite3_result_text(ctx, result, -1, g_free); >> } >> >> int main(int argc, char **argv) { >> sqlite3_config(SQLITE_CONFIG_LOG, log, NULL); >> sqlite3 *db = NULL; >> sqlite3_stmt *stmt = NULL; >> char *zErrMsg = NULL; >> const char *z; >> int rc = 0; >> rc = sqlite3_open_v2(":memory:", &db, SQLITE_OPEN_FULLMUTEX | >> SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); >> if (db == NULL || SQLITE_OK != rc) { >> fprintf(stderr, "Error: unable to open database: %s\n", >> sqlite3_errmsg(db)); >> exit(1); >> } >> sqlite3_create_function_v2(db, "regex_replace", 3, SQLITE_UTF8, 0, >> glibReplaceAllFunc, NULL, NULL, NULL); >> rc = sqlite3_prepare_v2(db, "select regex_replace('.', 'abcde', r) >> from (select 'z' as r union all select 'y')", -1, &stmt, NULL); >> if (stmt == NULL || SQLITE_OK != rc) { >> fprintf(stderr, "Error: prepare stmt: %s\n", sqlite3_errmsg(db)); >> exit(1); >> } >> for (int i = 1; i <= 2; i++) { >> printf("loop %d\n", i); >> rc = sqlite3_step(stmt); >> while (rc == SQLITE_ROW) { >> z = (const char*)sqlite3_column_text(stmt, 0); >> printf("%s\n", z); >> rc = sqlite3_step(stmt); >> } >> if (SQLITE_OK != rc && SQLITE_DONE != rc) { >> fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); >> exit(1); >> } >> rc = sqlite3_reset(stmt); >> if (SQLITE_OK != rc) { >> fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); >> exit(1); >> } >> } >> sqlite3_finalize(stmt); >> sqlite3_close(db); >> } >> _______________________________________________ >> sqlite-users mailing list >> sqlite-users@sqlite.org >> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users >> > > > > -- > D. Richard Hipp > d...@sqlite.org > _______________________________________________ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users