lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


* Sam Roberts:

> Maybe you should just try to do whatever it is you are trying to do,
> and see if it works?

Here's an example, to be used with the lua-sqlite3 binding you
mentioned:

----------------------------------------------------------------------
require "path"
require "sqlite3"

local db = sqlite3.open_memory()

assert(db:exec[[
  CREATE TABLE test (col1, col2);
  INSERT INTO test VALUES (1, 2);
  INSERT INTO test VALUES (2, 4);
]])


assert(db:set_function("my_sum", 2,
                       function(a, b)
                          local f = coroutine.wrap(
                             function ()
                                db:exec("SELECT 1")
                             end)
                          f()
                          f = nil
                          collectgarbage("collect")
                          return a + b
                       end))

for col1, col2, sum in db:cols("SELECT MAX(my_sum(col1, col2)) FROM test") do
   print(col1, col2, sum)
end
----------------------------------------------------------------------

What happens is that the call to exec in the my_sum user defined
function overwrites the stored L pointer in the db object, which
becomes dangling after the coroutine has been garbage-collected.
Running this example should result in a crash (segmentation fault)
and funny output using valgrind.

> Btw, if you think this is an issue for something like user-defined
> functions in sqlite, maybe try reading the sqlite bindings, the docs
> indicate they do user-defined functions:
>
>   http://www.nessie.de/mroth/lua-sqlite3/documentation.html#ref17

Thanks for the pointer, but I was writing the binding as an exercise,
to become familiar with Lua's C API.

Actually, despite the issue I'm trying to explain, the C API is very
nice.  It's less error-prone to write glue code than for other C APIs
I've used (it's also much better documented than what I'm used to).