I feel the need to wrap an SQLite printf-like function into a scalar
I wish to use it as in:
select printf(format_string, list of arguments);
My question is slightly off topic but there are experienced users here
who have probably done it before.
In the scalar function (printf), I get arguments as the usual array of
pointers. How would you pass the variable list arguments to
Is there any nice way not imposing a limitation on n?
Jean-Christophe Deschamps wrote:
> I feel the need to wrap an SQLite printf-like function into a scalar
You can just do that sort of thing in your application. There is no need to
do it via a SQL function.
> My question is slightly off topic but there are experienced users here
> who have probably done it before.
You can retrieve any value as any type. For example if an integer is
returned but you call column_text then it will be converted to text for you.
> In the scalar function (printf), I get arguments as the usual array of
> pointers. How would you pass the variable list arguments to
> Is there any nice way not imposing a limitation on n?
This kind of thing is extra-ordinarily tricky under C, error prone, easy to
crash and usually non-portable. This is how you receive a variable number
But what you are really trying to do is take an arbitrary number of
parameters, unwrap them from SQLite types into native types and then compose
a call to sqlite3_mprintf. The only way this is directly possible is using
a library that can do this for you at runtime which pretty much means this one:
Thank you for your answer. I knew from old days that va_* things are
very fragile (not only from the portability point of view).
In the "duct tape programming" situation where I currently am, the best
I can came up with is by fixing the max # of arguments to 32 and using
a _ugly_ kludge on the stack. It gives something along the line of:
abc -357 Febæhùivê 1No 2No <NULL> 3.14159 ÅDEFÀSSÙÇ 1234567890123456
I confess that the way I pass sqlite3_mprintf(fmt, stuff) the "stuff"
structure containing ... ahem ... exactly what the stack is supposed to
contain is probably not a very academic programming model. (but it
works >:-} )
>Perhaps this might lead you in the right direction Jean-Christophe ...
Thank you for your answer.
The va_* construct isn't portable, AFAIK. Various compilers (headers,
libraries) may (and did) implement it in different and potentially
Since in my case I have homebrew extensions, stock sqlite3.dll and
third-party software, all compiled with distinct compilers, I've
avoided using va_*.
In fact, this is a bit pedantic, since what I've done (packing
arguments in a structure which is pushed on the stack) is strictly
equivalent to the "packed array" va_* variation and is simply what the
stack would look like if individual parameters were pushed naturally in
a standard multi-parameter function call. The drawback is that the
maximum number for parameters must be fixed, but I guess this is harder
to circumvent (in C).
Some day when/if I get spare time, I'll reimplement the printf
extension, remove what's useless here (eg %c) and make it a bit more
robust (force ll prefix for integers, a.s.o.) but this is very low
priority for now.