On Fri Oct 28, 2016 at 05:48:48PM +0700, Dan Kennedy wrote:
> On 10/28/2016 05:39 PM, [email protected] wrote:
> > Hi Rowan,
> >
> > On Fri Oct 28, 2016 at 06:19:59PM +0800, Rowan Worth wrote:
> > > Every sqlite_stmt you use *must* be finalized via sqlite3_finalize.
> > > I'm not exactly sure what that looks like from the other side of DBD,
> > > but I would be checking your perl code for a statement/resultset
> > > object which outlives the database connection itself.
> > >
> > Some of my new debug statements appear to confirm that: database
> > handles are being cleaned up before statement handles, even though
> > presumably the statement handle still has a reference back to the
> > database.
>
> SQLite should handle that. If you call sqlite3_close() before all statement
> handles have been cleaned up, the call fails with SQLITE_MISUSE. Or if you
> use sqlite3_close_v2(), the call succeeds, but a reference count is used to
> ensure that the db handle object is not actually deleted until all
> statements are. close_v2() was added for this situation - where a garbage
> collectors or similar is responsible for closing db handles and finalizing
> statements.
The "handles" I was referring to above were Perl DBI handles. No doubt
they contain a real SQLite handle somewhere, but I don't think it is
safe to assume a one-to-one mapping. For example, the following appears
to create two Perl objects for each of the $db and $sth variables:
use DBI;
sub DBI::db::DESTROY {
warn "DESTROY @_";
}
sub DBI::st::DESTROY {
warn "DESTROY @_";
}
my $db = DBI->connect('dbi:SQLite:dbname=:memory:');
my $sth = $db->prepare('select 1');
# DESTROY DBI::db=HASH(0x9acf68c) at x line 4.
# DESTROY DBI::st=HASH(0x9acf95c) at x line 8.
# DESTROY DBI::st=HASH(0x9acf754) at x line 8.
# DBI st handle 0x9acf95c has uncleared implementors data.
# dbih_clearcom (sth 0x9acf95c, com 0x9ad1518, imp
DBD::SQLite::st):
# FLAGS 0x100113: COMSET IMPSET Warn PrintError
PrintWarn
# PARENT DBI::db=HASH(0x9acf600)
# KIDS 0 (0 Active)
# NUM_OF_FIELDS 1
# NUM_OF_PARAMS 0
# DESTROY DBI::db=HASH(0x9acf600) at x line 4.
# DBI db handle 0x9acf68c has uncleared implementors data.
# dbih_clearcom (dbh 0x9acf68c, com 0x9ac1fd8, imp
DBD::SQLite::db):
# FLAGS 0x100317: COMSET IMPSET Active Warn PrintError
# PrintWarn AutoCommit
# PARENT DBI::dr=HASH(0x9acf1a0)
# KIDS 0 (0 Active)
#
It is not obvious to me why that is so and I don't know the DBD::SQLite
code base so I won't speculate.
> If this is repeatable, try running it under valgrind. The valgrind
> error should make it pretty clear whether or not the statement handle
> really has already been finalized.
Well I have found what is probably the original source of the error: I
was keeping (Perl) statement handles around after the database handles
had expired. That doesn't mean that there isn't an issue with
how DBD::SQLite is using SQLite, but I no longer have the motivation to
track down that error when the easy answer to my problem is "don't do
that." Plus I have another error to report in a new thread :-(
Thanks everyone for listening.
--
Mark Lawrence
_______________________________________________
sqlite-users mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users