wxSQLite3Statement problem

Talk here about issues with one of the components hosted at wxCode, or suggest features for it.
silverstorm82
Knows some wx things
Knows some wx things
Posts: 32
Joined: Wed Aug 17, 2011 5:13 pm

wxSQLite3Statement problem

Postby silverstorm82 » Thu Dec 01, 2011 9:35 am

Hello anybody,

I am currently facing a problem using the wxSQLite3Statement classes. What I am trying to do is to choose between several statements at runtime and execute the chosen one using a pointer. At the same time, depending on the chosen statement, I would like to bind one parameter to the statement:

Code: Select all

wxSQLite3Statement* pStmt;

if (foo)
   pStmt = new wxSQLite3Statement(statement1);
else
  pStmt = new wxSQLite3Statement(statement2);

if (foo)
  pSmt->Bind(1, wxT("value"));

wxSQLite3ResultSet result pStmt->ExecuteQuery();
// [Processing of result here]

result.Finalize();
pStmt->Reset();
delete pStmt;


What happens is that when running this code more than one time it crashes at the ExecuteQuery() statement with an unhandled exception with is not an wxSQLite3Exception (that one is catched as the code lies within a try-catch block.

I am pretty sure that I am using the classes in a wrong way but unfortunately I don't know where the error and I also don't know which kind of exception is thrown here.

Any ideas?

Greetings,
Jens

silverstorm82
Knows some wx things
Knows some wx things
Posts: 32
Joined: Wed Aug 17, 2011 5:13 pm

Re: wxSQLite3Statement problem

Postby silverstorm82 » Thu Dec 01, 2011 11:08 am

I just solved the problem - at least I found a work around:

I changed the lines to read

Code: Select all

if (foo)
   pStmt = &statement1;
else
  pStmt = &statement2;


and removed the delete statement at the end of the code. Now it works but I still don't now the actual problem :-(

User avatar
doublemax
Moderator
Moderator
Posts: 11528
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxSQLite3Statement problem

Postby doublemax » Thu Dec 01, 2011 11:50 am

Your problem may be related to this post:
viewtopic.php?f=34&t=28933
Use the source, Luke!

silverstorm82
Knows some wx things
Knows some wx things
Posts: 32
Joined: Wed Aug 17, 2011 5:13 pm

Re: wxSQLite3Statement problem

Postby silverstorm82 » Thu Dec 01, 2011 12:33 pm

Thanks for your answer, doublemax. I am reallly curious about the problem.

I checked/read that thread before I posted my code but I think that's a different issue: I am not trying to use a resultset out of the functions scope but inside the function and the crash does not occur when trying to use the resultset but when executing the query/statement and only when executing the statement a second time (the first time always works).

User avatar
doublemax
Moderator
Moderator
Posts: 11528
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxSQLite3Statement problem

Postby doublemax » Thu Dec 01, 2011 1:13 pm

I'm almost certain the issue is related, but i don't know the wxSQlite internals too well.

But Ulrich Telle the author of wxSQLite reads this forum, i'm sure he has an explanation if he reads this :)
Use the source, Luke!

utelle
Moderator
Moderator
Posts: 767
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxSQLite3Statement problem

Postby utelle » Fri Dec 02, 2011 8:23 am

silverstorm82 wrote:I just solved the problem - at least I found a work around:

I changed the lines to read

Code: Select all

if (foo)
   pStmt = &statement1;
else
  pStmt = &statement2;


and removed the delete statement at the end of the code. Now it works but I still don't now the actual problem :-(

As doublemax noted in his post I read this forum regularly ... but I somehow missed this thread yesterday evening. #-o

The problem in your first code version is that the ownership of the internal SQLite statement is passed on to the newly created wxSQLite3Statement instance. On executing delete for this instance the internal SQLite statement is finalized thus the SQLite statement pointer in your statement1 resp. statement2 instance isn't valid any longer. Probably SQLite clears one of it's internal pointers resulting in using a NULL pointer on using the statement a second time producing an access violation exception.

Your second approach is the right one as just pointing to the statement avoids passing the ownership away from the original statement. Alternatively you could use references instead of pointers although it doesn't make much difference.

Regards,

Ulrich

silverstorm82
Knows some wx things
Knows some wx things
Posts: 32
Joined: Wed Aug 17, 2011 5:13 pm

Re: wxSQLite3Statement problem

Postby silverstorm82 » Fri Dec 02, 2011 11:57 am

Hello Ulrich,

The problem in your first code version is that the ownership of the internal SQLite statement is passed on to the newly created wxSQLite3Statement instance. On executing delete for this instance the internal SQLite statement is finalized thus the SQLite statement pointer in your statement1 resp. statement2 instance isn't valid any longer.

I don't understand why the original statement1 resp. statement2 are not valid any longer because I created, used and deleted a copy of the statements (pStmt = new wxSQLite3Statement(statement1)). Do you have any explanation for that? I'd like to understand that.

Greetings,
Jens

utelle
Moderator
Moderator
Posts: 767
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxSQLite3Statement problem

Postby utelle » Fri Dec 02, 2011 2:54 pm

Hi Jens,
silverstorm82 wrote:
The problem in your first code version is that the ownership of the internal SQLite statement is passed on to the newly created wxSQLite3Statement instance. On executing delete for this instance the internal SQLite statement is finalized thus the SQLite statement pointer in your statement1 resp. statement2 instance isn't valid any longer.

I don't understand why the original statement1 resp. statement2 are not valid any longer because I created, used and deleted a copy of the statements (pStmt = new wxSQLite3Statement(statement1)). Do you have any explanation for that? I'd like to understand that.

Ok, so here comes the whole story in greater detail:

A prepared SQL statement is represented by an opaque data structure by SQLite and SQLite returns a pointer to this data structure. wxSQLite3Statement is just a wrapper class for this statement pointer. The problem is that SQLite requires that a statement is finalized after use otherwise you get in trouble, i.e. you'll experience deadlocks or other problems. But to make matters complicated a statement can be finalized only once. So I introduced the concept of "ownership" into class wxSQLite3Statement. Only one instance can hold the ownership of the associated statement pointer and is responsible for finalizing the statement. If you use the copy constructor as in your code (or the assignment operator) the ownership is forwarded to the wxSQLite3Statement target instance. The source instance looses the ownership (in your code: statement1 and statement2 loose ownership). Nevertheless the statement pointer is valid for both instances as long as it was not finalized. But in your code the statement is implicitly finalized on executing delete pStmt.

As soon as a wxSQLite3Statement instance goes out of scope or is deleted, it's destructor is called and looks at the ownership indicator. If the instance owns the statement pointer it finalizes the statement. Thereafter no other wxSQLite3Statement instance holding a copy of the statement pointer can access the statement. If you do the application will crash.

Unfortunately there is no way to detect whether a statement pointer is still valid or not. Sure one could keep track of all instances holding statement pointers, but keep in mind that wxSQLite3 is a thin wrapper around SQLite. In most scenarios you don't pass around wxSQLite3Statement instances a lot and there is little gain from keeping track because you would always have to check whether the statement was finalized or not. Therefore I decided to not add this feature to wxSQLite3.

Regards,

Ulrich

silverstorm82
Knows some wx things
Knows some wx things
Posts: 32
Joined: Wed Aug 17, 2011 5:13 pm

Re: wxSQLite3Statement problem

Postby silverstorm82 » Fri Dec 02, 2011 7:54 pm

Hello Ulrich,

got it, thank you :-)

Greetings,
Jens

utelle
Moderator
Moderator
Posts: 767
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxSQLite3Statement problem

Postby utelle » Fri Jan 20, 2012 5:55 pm

Yesterday I released version 3.0.0 of wxSQLite3. In this new version I dropped the concept of SQLite statement pointer ownership in favor of reference counted pointers. This should allow more flexible use of wxSQLite3Statement instances. The underlying SQLite statement is automatically finalized when the last wxSQLite3Statement instance referencing it goes out of scope. Nevertheless explicitly finalizing is usually recommended.

Regards,

Ulrich

silverstorm82
Knows some wx things
Knows some wx things
Posts: 32
Joined: Wed Aug 17, 2011 5:13 pm

Re: wxSQLite3Statement problem

Postby silverstorm82 » Thu Jan 26, 2012 12:22 am

Hello Ulrich,

thank you for the update.

Unfortunately there is a problem with this new version at least on my machine: As soon as I open a database file, I get an access violation in one of the wxWidgets files. This access violation does not happen when using version 2.1.3. I cannot tell the line of code but I think it happens when a windows message is processed. Any ideas?

Greetings,
Jens

utelle
Moderator
Moderator
Posts: 767
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxSQLite3Statement problem

Postby utelle » Thu Jan 26, 2012 7:30 pm

silverstorm82 wrote:Unfortunately there is a problem with this new version at least on my machine: As soon as I open a database file, I get an access violation in one of the wxWidgets files. This access violation does not happen when using version 2.1.3. I cannot tell the line of code but I think it happens when a windows message is processed. Any ideas?

As we discussed by private mail the problem arises since method Reset is called on an already finalized statement in your code. But it's also a bug in the latest version of wxSQLite3 in method wxSQLite3Statement::Reset: the validity of the internal SQLite statement isn't checked correctly.

Edited (February 2, 2012):
wxSQLite3 version 3.0.0.1 released today fixes the bug.

Regards,

Ulrich


Return to “wxCode”

Who is online

Users browsing this forum: No registered users and 2 guests