QSqlQueryModel::setQuery - SIGSEGV
I'm using Linux / Qt 4.5.0.
Most sql work is going fine except for this piece of code where I'm using QSqlQueryModel for the first time:
Code:
QSqlQuery query
("SELECT name FROM videosource ");
model->setQuery(query);
model->setQuery(query) blows out; top of stack is:
Quote:
Thread [1] (Suspended: Signal 'SIGSEGV' received. Description: Segmentation fault.)
36 mysql_stmt_num_rows() 0x046afaa7
35 QSqlQuery::size() /media/OneTouch4-Main/internet/downloads/QT4.5Preview/qt-x11-opensource-src-4.5.0-snapshot-20081217/src/sql/kernel/qsqlquery.cpp:717 0x00232cfd
34 QSqlQueryModel::setQuery() /media/OneTouch4-Main/internet/downloads/QT4.5Preview/qt-x11-opensource-src-4.5.0-snapshot-20081217/src/sql/models/qsqlquerymodel.cpp:347 0x00246acf
...
mysql_stmt_num_rows() is presumably in a mysql library somewhere so I'm guessing there is an issue between QSql and mysql.
(The query "SELECT name FROM videosource" works fine in other situations.)
Anyone seen this kind of problem before?
Re: QSqlQueryModel::setQuery - SIGSEGV
Please check your code again, the problem has to be elsewhere. Are you using the database from multiple threads maybe?
Re: QSqlQueryModel::setQuery - SIGSEGV
Thank you for your suggestion wysota.
I extracted the relevant bits of code and tested this threadless morsel:
Code:
int main(int argc, char *argv[])
{
db.setHostName("localhost");
db.setDatabaseName("mythconverg");
bool trashok;
db.
setPort(QString("3306").
toInt(&trashok
));
db.setUserName("mythtv");
db.setPassword("mythtv");
bool ok = db.open();
if (ok) qDebug() << "Open OK";
else qDebug() << "Open failed";
amodel.setQuery("SELECT sourceid FROM videosource"); //BANG! SIGSEGV
...
}
So then I reverted from the Qt 4.5.0 snapshot to 4.4.3. and setQuery then worked as advertised. I will try picking up the latest 4.5 snapshot tomorrow to see if that has fixed anything.
Re: QSqlQueryModel::setQuery - SIGSEGV
I've just tried 4.5.0Beta1. It blows out too.
There is something fishy about the mysql driver; the working version (4.4.3) of libqsqlmysql.so is larger than the non-working 4.5.0 versions although they were all built the same way with the same set of header files. Am currently investigating but would appreciate any insights.
Re: QSqlQueryModel::setQuery - SIGSEGV
try to create QSqlQueryModel in the heap using operator new.
Re: QSqlQueryModel::setQuery - SIGSEGV
Thanks spirit for the suggestion. Creating on the heap makes no difference.
Playing around with the debugger gave me the feeling that there was a linkage problem somewhere so in desperation I swapped the 4.5.0 mysql drivers (libqsqlmysql.so & libqsqlmysql.so.debug) for the 4.4.3 versions. Hey presto - everything works.
I'm not happy about this however as the libraries are not the same size between versions and I'm sure something will bite me soon.
I've tried recompiling the drivers and Qt itself with different sql options but no joy.
More suggestions please chaps!
Re: QSqlQueryModel::setQuery - SIGSEGV
Do the Qt SQL examples work properly?
Re: QSqlQueryModel::setQuery - SIGSEGV
Thanks again wysota. Now why didn't I think of trying the examples?
Out of the box the sqlqyerymodel examples work fine, but then I found that they use the sqlite drivers.
If I modify them to use MySql drivers the behaviour is as before: OK with 4.4.3 driver, core dump with 4.5.0.
Re: QSqlQueryModel::setQuery - SIGSEGV
I've spent a day completely reinstalling MySql, QT and various devel packages; then compiling everything from scratch. Result: No difference at all! Qt4.4.3 works, Qt4.5.0Beta doesn't.
To recap:
Code:
amodel.setQuery("SELECT sourceid FROM videosource"); //BANG! SIGSEGV
Reason for segv: setQuery() eventually calls QMYSQLResult::size in file: $QTDIR/src/sql/drivers/mysql/qsql_mysql.cpp
Here's the code:
Code:
int QMYSQLResult::size()
{
if (isSelect())
if (d->d->preparedQuerys)
#if MYSQL_VERSION_ID >= 40108
return int(mysql_stmt_num_rows(d->stmt)); //<---we get here but d->stmt is null
#else
return -1;
#endif
else
return int(mysql_num_rows(d->result)); //<--- d->result is not null, maybe we should have got here
else
return -1;
}
When mysql_stmt_num_rows(d->stmt) is called it blows because d->stmt is 0x0.
Well I assume that's the reason; mysql_stmt_num_rows is in a mysql library and expects to see a "struct st_mysql_stmt" pointer.
I think I'll just put this down to a bug and move on - unless it rings any bells with anyone?
Re: QSqlQueryModel::setQuery - SIGSEGV
Maybe the problem is not with Qt but with MySQL? Anyway you should report the problem to Qt Software - remember Qt4.5 is still in development phase.
Re: QSqlQueryModel::setQuery - SIGSEGV
Will do, thanks for your support.
Re: QSqlQueryModel::setQuery - SIGSEGV
Solved!
The MySql driver in 4.5.0 incorrectly treat this code:
Code:
model.setQuery("SELECT sourceid FROM videosource");
as:
Code:
model.
setQuery(QSqlQuery("SELECT sourceid FROM videosource"));
which is fine except that the QSqlQuery is later treated as a prepared query which it obviously isn't (see annotated code in previous post in this thread); the 4.4.3 driver doesn't make this mistake.
Workaround:
Code:
query.prepare("SELECT sourceid FROM videosource");
query.exec(); //must do this explicitly
model->setQuery(query);
I have reported this as a bug [#242208].
Thanks to all for help and support.
Re: QSqlQueryModel::setQuery - SIGSEGV
Update:
The same bug rears its ugly head in this snippet:
Code:
sourcesTableModel->setTable("videosource");
sourcesTableModel->select(); //BANG! SIGSEGV
Re: QSqlQueryModel::setQuery - SIGSEGV
I assure you I'm working with QtSQL almost every day and such statements work just fine :) Your problem is related strictly to your installation and/or the version of Qt and/or MySQL you are using. If changing the version of Qt doesn't help, try changing the version of MySQL client library you are using.
Re: QSqlQueryModel::setQuery - SIGSEGV
Thanks wysota - I had similar feedback from QT support regarding my bug report yesterday so I tried the latest snapshot; it works perfectly. :)
There had been several developments in qsql_mysql.cpp since the Beta1 release which were directly concerned with my problem.