I came across a problem with the new pointer-passing interface, when I
tried to incorporate the carray extension into my wxSQLite3 wrapper for
In the comment of the sqlite3_bind_pointer() routine I found this note:
The T parameter should be a static string, preferably a string literal.
This comment is a bit misleading, since it doesn't become clear that the
string pointer for T must be valid as long as the associated statement
In my case this is quite cumbersome, since in my wrapper I have to
extract the value of parameter T from a temporary string object. That
is, shortly after having called sqlite3_bind_pointer the temporary
string goes out of scope. The effect is that later on the function
sqlite3_value_pointer usually can't see the correct type value anymore.
Therefore sqlite3_value_pointer returns a NULL pointer ... and the
carray table is empty.
IMHO it would be better if the function sqlite3_bind_pointer would make
a copy of the type string and would thus be independent of the life span
of the type parameter.
Re: Problem with the new pointer-passing interface
> To me it seems like that string is very tightly coupled with the actual pointer being bound.
No, not really. The type string is tightly coupled with the extension module which uses the pointer. The type string allows the extension module to check whether the pointer is really meant to be handled by the module.
For the carray module the pointer just pints to a C++ array of integers, doubles or strings. So there is no simple way to attach the type string to this data structure.
> I think it's a good idea, in case you cannot make it a literal or static, to keep it with
> an object whose pointer you bind.
The problem is that my component just provides a thin wrapper for SQLite for applications based on the wxWidgets library. In most cases the wrapper just passes given parameters on to the underlying SQLite functions. That is, the wrapper itself doesn't know anything about internals of extension modules and pointer objects they might be able to handle.
I could introduce a wrapper object for pointers that additionally contains a type string, but then I would have to keep track of wrapper objects, since only the raw pointer is passed on to the extension module. In fact, this would not solve the problem.
IMHO it should be rather simple to adjust the SQLite functions of the new pointer-passing interface to make a copy of the type string on binding a pointer and releasing the copy when the pointer value goes out of scope.
> On 8/3/17, Ulrich Telle <[hidden email]> wrote:
> > The description of the new pointer-passing interface gives the impression
> > that restricting the pointer type parameter to static strings or literals
> > prevents misuse of the new feature. And that is definitely not the case. It
> > might be a hurdle for unsophisticated developers, but not for the
> > experienced ones.
> The documentation has now been adjusted to try to make it clear that
> the static string requirement simply makes misuse of the interface
> more difficult, not impossible.
Thanks. Certainly a valid point to not impose a runtime penalty on applications not using the pointer interface.
As said I solved the issue for my SQLite wrapper. The solution only affects the calls to the pointer interface (like binding a pointer to a SQL parameter).
On Thu, Aug 03, 2017 at 12:33:05PM +0300, Paul wrote:
> To me it seems like that string is very tightly coupled with the
> actual pointer being bound. I think it's a good idea, in case you
> cannot make it a literal or static, to keep it with an object whose
> pointer you bind.
Rhetorical: Why not use the pointer value itself then instead of the
contents of the string? After all, the string should just be a .text
section constant string...
Now, suppose that you're building FFI bindings for SQLite3 for some
programming language, e.g., Python. So you have a string from the
run-time for this language, but you can't ensure that it will have the
necessary lifetime. So now you have to make a copy. It's a bit of a
pain. SQLite3 could have made a copy itself.
On the flip side, it's possible that you have to do some conversions
anyways because SQLite3 deals with C strings and the target language
run-time deals with counted-codeunit strings or whatever.
So even if SQLite3 made a copy, the FFI bindings might have to make
their own copy anyways. Thus: who cares :)
Still, for many cases it will be easier to write code to this API if
SQLite3 makes its own copy.