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

Reply via email to