tableView->setModel(model); causes SIGSEGV.
-
Hi,
I am new to C++ and Qt. This is the 2nd day I have been trying to fix this and I can't get further (GPT4 is out of answers too).
I am on Manjaro, Qt 6.7.2. Using MariaDB.
I can see from the MariaDB log that the SQL is executed just fine by the query.But when I do "tableView->setModel(model);" it seg faults. I don't know where to look for more information with Qt Creator or C++. I have also tried a variant that uses bindValue(":field1", field1) but I guess the problem is elsewhere.
EDIT:
It is not here that it crashes >> tableView->setModel(model);
It seems it is in qsql_mysql.cpp:459.bool QMYSQLResult::fetch(int i){ ... int nRC = mysql_stmt_fetch(d->stmt); ...
In the below example there are no search criterias added so it doesn't bind anything.
void DatabaseHandler::getProducts(QTableView* tableView, const QString field1, const QString field2, const bool useDateSearch, const QDate dateMin, const QString field3, int prodCount, int queryTimeout) { if (!db.isOpen()) { qCritical() << "Database is not open."; //emit errorOccurred(db.lastError().text()); return; } QString queryString = QString( "SELECT " "field1 , " "field2, " "prodCount , " "field3 , " "prod_date " "FROM products " "WHERE 1 = 1"); if (!field1.isEmpty()) { queryString += field1.contains('%') ? " AND field1 LIKE ?" : " AND field1 = ?"; } if (!field2.isEmpty()) { queryString += field2.contains('%') ? " AND field2 LIKE ?" : " AND field2 = ?"; } if (useDateSearch && dateMin.isValid()) { queryString += " AND prod_date >= ?"; } if (!field3.isEmpty()) { queryString += " AND field3 = ?"; } if (prodCount > 0) { queryString += " AND prodCount >= ?"; } queryString += " ORDER BY prod_date DESC;"; QSqlQuery query(db); query.prepare(queryString); if(HasError(query)) return; if (!field1.isEmpty()) { query.addBindValue(field1); if(HasError(query)) return; } if (!field2.isEmpty()) { query.addBindValue(field2); if(HasError(query)) return; } if (useDateSearch && dateMin.isValid()) { query.addBindValue(dateMin); if(HasError(query)) return; } if (!field3.isEmpty()) { query.addBindValue(field3); if(HasError(query)) return; } if (prodCount > 0) { query.addBindValue(prodCount); if(HasError(query)) return; } query.exec(); if(HasError(query)) return; QSqlQueryModel* model = new QSqlQueryModel(this); if(HasError(model)) return; model->setQuery(std::move(query)); if(HasError(model)) return; model->setHeaderData(0, Qt::Horizontal, "Field 1", Qt::ImReadOnly); model->setHeaderData(1, Qt::Horizontal, "Field 2", Qt::ImReadOnly); model->setHeaderData(2, Qt::Horizontal, "Field 3", Qt::ImReadOnly); model->setHeaderData(3, Qt::Horizontal, "Field 4", Qt::ImReadOnly); model->setHeaderData(4, Qt::Horizontal, "Field 5", Qt::ImReadOnly); qDebug() << "HERE"; tableView->setModel(model); qDebug() << "HERE2"; tableView->show(); }
Locals model 0x0 QSqlQueryModel* prodCount -1 int query @0x5555558149e0 QSqlQuery queryString <not accessible> QString queryTimeout 1433365632 int dateMin Sat Feb 28 -4713 QDate field3 <not accessible> QString tableView 0x0 QTableView* this 0x0 DatabaseHandler* useDateSearch false bool field1 <not accessible> QString field2 <not accessible> QString Inspector Expressions Return Value Tooltip Qt <no such value>
-
Hi,
I am new to C++ and Qt. This is the 2nd day I have been trying to fix this and I can't get further (GPT4 is out of answers too).
I am on Manjaro, Qt 6.7.2. Using MariaDB.
I can see from the MariaDB log that the SQL is executed just fine by the query.But when I do "tableView->setModel(model);" it seg faults. I don't know where to look for more information with Qt Creator or C++. I have also tried a variant that uses bindValue(":field1", field1) but I guess the problem is elsewhere.
EDIT:
It is not here that it crashes >> tableView->setModel(model);
It seems it is in qsql_mysql.cpp:459.bool QMYSQLResult::fetch(int i){ ... int nRC = mysql_stmt_fetch(d->stmt); ...
In the below example there are no search criterias added so it doesn't bind anything.
void DatabaseHandler::getProducts(QTableView* tableView, const QString field1, const QString field2, const bool useDateSearch, const QDate dateMin, const QString field3, int prodCount, int queryTimeout) { if (!db.isOpen()) { qCritical() << "Database is not open."; //emit errorOccurred(db.lastError().text()); return; } QString queryString = QString( "SELECT " "field1 , " "field2, " "prodCount , " "field3 , " "prod_date " "FROM products " "WHERE 1 = 1"); if (!field1.isEmpty()) { queryString += field1.contains('%') ? " AND field1 LIKE ?" : " AND field1 = ?"; } if (!field2.isEmpty()) { queryString += field2.contains('%') ? " AND field2 LIKE ?" : " AND field2 = ?"; } if (useDateSearch && dateMin.isValid()) { queryString += " AND prod_date >= ?"; } if (!field3.isEmpty()) { queryString += " AND field3 = ?"; } if (prodCount > 0) { queryString += " AND prodCount >= ?"; } queryString += " ORDER BY prod_date DESC;"; QSqlQuery query(db); query.prepare(queryString); if(HasError(query)) return; if (!field1.isEmpty()) { query.addBindValue(field1); if(HasError(query)) return; } if (!field2.isEmpty()) { query.addBindValue(field2); if(HasError(query)) return; } if (useDateSearch && dateMin.isValid()) { query.addBindValue(dateMin); if(HasError(query)) return; } if (!field3.isEmpty()) { query.addBindValue(field3); if(HasError(query)) return; } if (prodCount > 0) { query.addBindValue(prodCount); if(HasError(query)) return; } query.exec(); if(HasError(query)) return; QSqlQueryModel* model = new QSqlQueryModel(this); if(HasError(model)) return; model->setQuery(std::move(query)); if(HasError(model)) return; model->setHeaderData(0, Qt::Horizontal, "Field 1", Qt::ImReadOnly); model->setHeaderData(1, Qt::Horizontal, "Field 2", Qt::ImReadOnly); model->setHeaderData(2, Qt::Horizontal, "Field 3", Qt::ImReadOnly); model->setHeaderData(3, Qt::Horizontal, "Field 4", Qt::ImReadOnly); model->setHeaderData(4, Qt::Horizontal, "Field 5", Qt::ImReadOnly); qDebug() << "HERE"; tableView->setModel(model); qDebug() << "HERE2"; tableView->show(); }
Locals model 0x0 QSqlQueryModel* prodCount -1 int query @0x5555558149e0 QSqlQuery queryString <not accessible> QString queryTimeout 1433365632 int dateMin Sat Feb 28 -4713 QDate field3 <not accessible> QString tableView 0x0 QTableView* this 0x0 DatabaseHandler* useDateSearch false bool field1 <not accessible> QString field2 <not accessible> QString Inspector Expressions Return Value Tooltip Qt <no such value>
@snubben said in tableView->setModel(model); causes SIGSEGV.:
model 0x0
As you can see your model pointer is a nullptr, same goes for tableview and 'this' pointer.
-
@snubben said in tableView->setModel(model); causes SIGSEGV.:
model 0x0
As you can see your model pointer is a nullptr, same goes for tableview and 'this' pointer.
@Christian-Ehrlicher said in tableView->setModel(model); causes SIGSEGV.:
@snubben said in tableView->setModel(model); causes SIGSEGV.:
model 0x0
As you can see your model pointer is a nullptr, same goes for tableview and 'this' pointer.
OK, so if I comment out
tableView->setModel(model);
the application runs fine (except it is not showing data). I would expect it to crash and burn since I am using the model pointer for other things but it is not(?). But there is much I don't know about Qt/C++.
I have seen that under "Locals" before, sometimes it shows what looks like a valid address, sometimes not. I wonder if I am doing something wrong debugging. I used "Jump to line" to get to the position of "setmodel()". Debugging is so different from VS.I can post only every 600 secs, can you upvote my initial post? I'll be gray and in a wheelchair otherwise before this thread is solved.
-
OK, I hit the F5 now while debugging to get to the location where it crashes. Now it shows valid values.
Locals model @0x5555557a9750 QSqlQueryModel prodCount 0 int query @0x7fffffffdaa0 QSqlQuery queryString "SELECT field1, field2, prodCount, field3, prod_date FROM products WHERE 1 = 1 ORDER BY prod_date DESC;" QString queryTimeout 0 int dateMin Sat Jan 1 2000 QDate field3 "" QString tableView @0x5555557dfbe0 QTableView this @0x555555714c70 DatabaseHandler useDateSearch false bool field1 "" QString field2 "" QString Inspector Expressions Return Value Tooltip
-
OK, I hit the F5 now while debugging to get to the location where it crashes. Now it shows valid values.
Locals model @0x5555557a9750 QSqlQueryModel prodCount 0 int query @0x7fffffffdaa0 QSqlQuery queryString "SELECT field1, field2, prodCount, field3, prod_date FROM products WHERE 1 = 1 ORDER BY prod_date DESC;" QString queryTimeout 0 int dateMin Sat Jan 1 2000 QDate field3 "" QString tableView @0x5555557dfbe0 QTableView this @0x555555714c70 DatabaseHandler useDateSearch false bool field1 "" QString field2 "" QString Inspector Expressions Return Value Tooltip
-
Hi,
I am new to C++ and Qt. This is the 2nd day I have been trying to fix this and I can't get further (GPT4 is out of answers too).
I am on Manjaro, Qt 6.7.2. Using MariaDB.
I can see from the MariaDB log that the SQL is executed just fine by the query.But when I do "tableView->setModel(model);" it seg faults. I don't know where to look for more information with Qt Creator or C++. I have also tried a variant that uses bindValue(":field1", field1) but I guess the problem is elsewhere.
EDIT:
It is not here that it crashes >> tableView->setModel(model);
It seems it is in qsql_mysql.cpp:459.bool QMYSQLResult::fetch(int i){ ... int nRC = mysql_stmt_fetch(d->stmt); ...
In the below example there are no search criterias added so it doesn't bind anything.
void DatabaseHandler::getProducts(QTableView* tableView, const QString field1, const QString field2, const bool useDateSearch, const QDate dateMin, const QString field3, int prodCount, int queryTimeout) { if (!db.isOpen()) { qCritical() << "Database is not open."; //emit errorOccurred(db.lastError().text()); return; } QString queryString = QString( "SELECT " "field1 , " "field2, " "prodCount , " "field3 , " "prod_date " "FROM products " "WHERE 1 = 1"); if (!field1.isEmpty()) { queryString += field1.contains('%') ? " AND field1 LIKE ?" : " AND field1 = ?"; } if (!field2.isEmpty()) { queryString += field2.contains('%') ? " AND field2 LIKE ?" : " AND field2 = ?"; } if (useDateSearch && dateMin.isValid()) { queryString += " AND prod_date >= ?"; } if (!field3.isEmpty()) { queryString += " AND field3 = ?"; } if (prodCount > 0) { queryString += " AND prodCount >= ?"; } queryString += " ORDER BY prod_date DESC;"; QSqlQuery query(db); query.prepare(queryString); if(HasError(query)) return; if (!field1.isEmpty()) { query.addBindValue(field1); if(HasError(query)) return; } if (!field2.isEmpty()) { query.addBindValue(field2); if(HasError(query)) return; } if (useDateSearch && dateMin.isValid()) { query.addBindValue(dateMin); if(HasError(query)) return; } if (!field3.isEmpty()) { query.addBindValue(field3); if(HasError(query)) return; } if (prodCount > 0) { query.addBindValue(prodCount); if(HasError(query)) return; } query.exec(); if(HasError(query)) return; QSqlQueryModel* model = new QSqlQueryModel(this); if(HasError(model)) return; model->setQuery(std::move(query)); if(HasError(model)) return; model->setHeaderData(0, Qt::Horizontal, "Field 1", Qt::ImReadOnly); model->setHeaderData(1, Qt::Horizontal, "Field 2", Qt::ImReadOnly); model->setHeaderData(2, Qt::Horizontal, "Field 3", Qt::ImReadOnly); model->setHeaderData(3, Qt::Horizontal, "Field 4", Qt::ImReadOnly); model->setHeaderData(4, Qt::Horizontal, "Field 5", Qt::ImReadOnly); qDebug() << "HERE"; tableView->setModel(model); qDebug() << "HERE2"; tableView->show(); }
Locals model 0x0 QSqlQueryModel* prodCount -1 int query @0x5555558149e0 QSqlQuery queryString <not accessible> QString queryTimeout 1433365632 int dateMin Sat Feb 28 -4713 QDate field3 <not accessible> QString tableView 0x0 QTableView* this 0x0 DatabaseHandler* useDateSearch false bool field1 <not accessible> QString field2 <not accessible> QString Inspector Expressions Return Value Tooltip Qt <no such value>
Hi, the crucial parts are here
@snubben said in tableView->setModel(model); causes SIGSEGV.:
void DatabaseHandler::getProducts(QTableView* tableView,
and then here, where it seem to crash
tableView->setModel(model);
How do you pass the
view
to this function? How and where do you create it?Also:
if (!db.isOpen()) {
This looks like you store your
db
connection as private member inDatabaseHandler
.
Don't do that, it might cause undefined behavior. Better use the staticQSqlDatabase::database()
whenever it's needed. -
@JonB said in tableView->setModel(model); causes SIGSEGV.:
@snubben
You need to show the stack trace pane when it crashes (not the variables pane).1 mysql_stmt_fetch 0x7ffff0cf91e4 2 QMYSQLResult::fetch qsql_mysql.cpp 459 0x7ffff2a2b7da 3 QSqlQuery::seek qsqlquery.cpp 616 0x7ffff7f90b5d 4 QSqlQueryModel::data qabstractitemmodel.h 129 0x7ffff7f9b12b 5 QAbstractItemModel::multiData qabstractitemmodel.cpp 3681 0x7ffff69ac1df 6 QModelIndex::multiData qabstractitemmodel.h 496 0x7ffff7c69836 7 QStyledItemDelegate::initStyleOption qstyleditemdelegate.cpp 263 0x7ffff7c69836 8 QStyledItemDelegate::paint qstyleditemdelegate.cpp 374 0x7ffff7c68ee7 9 QTableViewPrivate::drawCell qtableview.cpp 1055 0x7ffff7c947d0 10 QTableView::paintEvent qtableview.cpp 1624 0x7ffff7c9f73c 11 QWidget::event qwidget.cpp 9405 0x7ffff79dbaee 12 QFrame::event qframe.cpp 521 0x7ffff7a69ae2 13 QCoreApplicationPrivate::sendThroughObjectEventFilters qcoreapplication.cpp 1281 0x7ffff6762efa 14 QCoreApplicationPrivate::sendThroughObjectEventFilters qcoreapplication.cpp 1268 0x7ffff6762efa 15 QApplicationPrivate::notify_helper qapplication.cpp 3281 0x7ffff79844e1 16 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1142 0x7ffff676318a 17 QCoreApplication::sendSpontaneousEvent qcoreapplication.cpp 1597 0x7ffff6763359 18 QWidgetPrivate::sendPaintEvent qwidget.cpp 5650 0x7ffff79d35d6 19 QWidgetPrivate::drawWidget qwidget.cpp 5600 0x7ffff79d3dde 20 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5779 0x7ffff79d51d9 21 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5765 0x7ffff79d4ff8 22 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5765 0x7ffff79d4ff8 23 QWidgetPrivate::drawWidget qwidget.cpp 5641 0x7ffff79d3ee0 24 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5779 0x7ffff79d51d9 25 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5765 0x7ffff79d4ff8 26 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5765 0x7ffff79d4ff8 27 QWidgetPrivate::drawWidget qwidget.cpp 5641 0x7ffff79d3ee0 28 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5779 0x7ffff79d51d9 29 QWidgetPrivate::drawWidget qwidget.cpp 5641 0x7ffff79d3ee0 30 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5779 0x7ffff79d51d9 31 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5765 0x7ffff79d4ff8 32 QWidgetPrivate::drawWidget qwidget.cpp 5641 0x7ffff79d3ee0 33 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5779 0x7ffff79d51d9 34 QWidgetPrivate::drawWidget qwidget.cpp 5641 0x7ffff79d3ee0 35 QWidgetRepaintManager::paintAndFlush qwidgetrepaintmanager.cpp 907 0x7ffff79e6665 36 QWidgetRepaintManager::sync qwidgetrepaintmanager.cpp 632 0x7ffff79e70bb 37 QWidgetWindow::event qwidgetwindow.cpp 310 0x7ffff79f0818 38 QApplicationPrivate::notify_helper qapplication.cpp 3287 0x7ffff79844f2 39 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1142 0x7ffff676318a 40 QCoreApplication::sendSpontaneousEvent qcoreapplication.cpp 1597 0x7ffff6763359 41 QGuiApplicationPrivate::processExposeEvent qguiapplication.cpp 3298 0x7ffff6fc9883 42 QWindowSystemInterface::sendWindowSystemEvents qwindowsysteminterface.cpp 1114 0x7ffff702277c 43 xcbSourceDispatch qxcbeventdispatcher.cpp 57 0x7ffff2ba2cda 44 ?? 0x7ffff5d94ab9 45 ?? 0x7ffff5df69e7 46 g_main_context_iteration 0x7ffff5d93fc5 47 QEventDispatcherGlib::processEvents qeventdispatcher_glib.cpp 394 0x7ffff6a1a76a 48 QEventLoop::exec qflags.h 34 0x7ffff676e963 49 QCoreApplication::exec qflags.h 74 0x7ffff676b41e 50 main main.cpp 10 0x55555555ee50
This?
So it seems it crashes somewhere else in regards to the "setModel(model)". I thought it crashed there and then.
-
Hi, the crucial parts are here
@snubben said in tableView->setModel(model); causes SIGSEGV.:
void DatabaseHandler::getProducts(QTableView* tableView,
and then here, where it seem to crash
tableView->setModel(model);
How do you pass the
view
to this function? How and where do you create it?Also:
if (!db.isOpen()) {
This looks like you store your
db
connection as private member inDatabaseHandler
.
Don't do that, it might cause undefined behavior. Better use the staticQSqlDatabase::database()
whenever it's needed.@Pl45m4 said in tableView->setModel(model); causes SIGSEGV.:
Hi, the crucial parts are here
@snubben said in tableView->setModel(model); causes SIGSEGV.:
void DatabaseHandler::getProducts(QTableView* tableView,
and then here, where it seem to crash
tableView->setModel(model);
I was wrong, it wasn't there it crashed but setting the model causes the crash.
How do you pass the
view
to this function? How and where do you create it?I have a widgetProducts where tableViewProducts is a member.
tableViewProducts = new QTableView(this); databaseHandler->getProducts(tableViewProducts, ....);
Also:
if (!db.isOpen()) {
This looks like you store your
db
connection as private member inDatabaseHandler
.
Don't do that, it might cause undefined behavior. Better use the staticQSqlDatabase::database()
whenever it's needed.I use this:
DatabaseHandler::DatabaseHandler(QObject *parent) : QObject(parent) { db = QSqlDatabase::addDatabase("QMYSQL"); } DatabaseHandler::~DatabaseHandler() { db.close(); } bool DatabaseHandler::openDatabase(const QString &hostname, const QString &database, const QString &username, const QString &password, int port) { db.setHostName(hostname); db.setDatabaseName(database); db.setUserName(username); db.setPassword(password); db.setPort(port); if (!db.open()) { QString message = "Error opening database. " + db.lastError().text(); emit sendMessage(message, 5000); return false; } emit sendMessage("Database open", 2000); return true; }
OK so I set this once but not keeping a reference to "db" and use
QSqlDatabase::database()
to get it later?
Why the hell is this flagged as spam??? -
Can I have this function scope of db? A bit cleaner code.
QSqlDatabase db = QSqlDatabase::database();
I changed the code to use only QSqlDatabase::database(). Still crashing. By the way, I have another query that works with the database, difference is that I return the records in a QStringList. In case it is relevant.
-
Iterate through the sqlquery results instead setting it to the model to see if it is still crashing. How did you build the Qt mysql plugin? Also I'm pretty sure query.exec() should not be called.
-
Can I have this function scope of db? A bit cleaner code.
QSqlDatabase db = QSqlDatabase::database();
I changed the code to use only QSqlDatabase::database(). Still crashing. By the way, I have another query that works with the database, difference is that I return the records in a QStringList. In case it is relevant.
@snubben said in tableView->setModel(model); causes SIGSEGV.:
QSqlDatabase db = QSqlDatabase::database();
I changed the code to use only QSqlDatabase::database(). Still crashing
I mentioned this because it's a cleaner solution. It wouldn't solve your crash issue anyway.
Edit:
As @Christian-Ehrlicher says above, thequery.exec()
+setQuery
in combination withstd::move
is also weird.
You set execute the query, then passing a move-constructed query to the model, leaving the initialquery
in an undefined state.
(using the forum search function, you will find a lot of topics on this, like this one)If I'm not mistaken
setQuery
will do the job for you.
Or you do it as shown in the QueryModel-Example. -
Iterate through the sqlquery results instead setting it to the model to see if it is still crashing. How did you build the Qt mysql plugin? Also I'm pretty sure query.exec() should not be called.
@Christian-Ehrlicher said in tableView->setModel(model); causes SIGSEGV.:
Iterate through the sqlquery results instead setting it to the model to see if it is still crashing. How did you build the Qt mysql plugin? Also I'm pretty sure query.exec() should not be called.
The documentation for QSqlQueryModel says
Resets the model and sets the data provider to be the given query. Note that the query must be active and must not be isForwardOnly().
Apparently query.exec() makes it active:
qDebug() << "Is active:" << query.isActive(); query.exec(); qDebug() << "Is active:" << query.isActive();
Is active: false Is active: true
I just did
query.exec(); while (query.next()) { QString field1 = query.value(0).toString(); QString field2 = query.value(1).toString(); qDebug() << "field1:" << field1 << ", field2:" << field2; }
and it works fine.
I built the mysql driver using
mkdir ~/dev/cpp/QtBuilds/build-sqldrivers cd build-sqldrivers qt-cmake -G Ninja ~/Qt/6.7.2/Src/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX="~/Qt/6.7.2/Src" -DMySQL_INCLUDE_DIR="/usr/include/mysql" -DMySQL_LIBRARY="/usr/lib/libmysqlclient.so" cmake --build . cmake --install .
and it didn't report errors.
In my application I have this so it finds the driver. This is the folder that "cmake --install ." installed to.QCoreApplication::addLibraryPath("/home/username/Qt/6.7.2/Src/lib/qt6/plugins");
@Christian-Ehrlicher said in tableView->setModel(model); causes SIGSEGV.:
Or you do it as shown in the QueryModel-Example.
Yes, a simple QString query like that works. But I need to search based on search criterias, thus the dynamic SQL. I haven't found that it is possible to bind values to the model.
-
@snubben said in tableView->setModel(model); causes SIGSEGV.:
QSqlDatabase db = QSqlDatabase::database();
I changed the code to use only QSqlDatabase::database(). Still crashing
I mentioned this because it's a cleaner solution. It wouldn't solve your crash issue anyway.
Edit:
As @Christian-Ehrlicher says above, thequery.exec()
+setQuery
in combination withstd::move
is also weird.
You set execute the query, then passing a move-constructed query to the model, leaving the initialquery
in an undefined state.
(using the forum search function, you will find a lot of topics on this, like this one)If I'm not mistaken
setQuery
will do the job for you.
Or you do it as shown in the QueryModel-Example.@Pl45m4 said in tableView->setModel(model); causes SIGSEGV.:
@snubben said in tableView->setModel(model); causes SIGSEGV.:
QSqlDatabase db = QSqlDatabase::database();
I changed the code to use only QSqlDatabase::database(). Still crashing
I mentioned this because it's a cleaner solution. It wouldn't solve your crash issue anyway.
Edit:
As @Christian-Ehrlicher says above, thequery.exec()
+setQuery
in combination withstd::move
is also weird.
You set execute the query, then passing a move-constructed query to the model, leaving the initialquery
in an undefined state.
(using the forum search function, you will find a lot of topics on this, like this one)If I'm not mistaken
setQuery
will do the job for you.
Or you do it as shown in the QueryModel-Example.If I use
model->setQuery("select * from products");
it works. It shows the data. But I cannot bind variables then. Again, I am 100% new to C++/Qt so might miss some fundamental principle on how to achieve this.
I see from the thread you linked that the query.exec(), std::move is also used there.
-
@Pl45m4 said in tableView->setModel(model); causes SIGSEGV.:
@snubben said in tableView->setModel(model); causes SIGSEGV.:
QSqlDatabase db = QSqlDatabase::database();
I changed the code to use only QSqlDatabase::database(). Still crashing
I mentioned this because it's a cleaner solution. It wouldn't solve your crash issue anyway.
Edit:
As @Christian-Ehrlicher says above, thequery.exec()
+setQuery
in combination withstd::move
is also weird.
You set execute the query, then passing a move-constructed query to the model, leaving the initialquery
in an undefined state.
(using the forum search function, you will find a lot of topics on this, like this one)If I'm not mistaken
setQuery
will do the job for you.
Or you do it as shown in the QueryModel-Example.If I use
model->setQuery("select * from products");
it works. It shows the data. But I cannot bind variables then. Again, I am 100% new to C++/Qt so might miss some fundamental principle on how to achieve this.
I see from the thread you linked that the query.exec(), std::move is also used there.
@snubben said in tableView->setModel(model); causes SIGSEGV.:
it works. It shows the data.
So now per your earlier debug information try the actual query which seems to be executed with your bindings:
SELECT field1, field2, prodCount, field3, prod_date FROM products WHERE 1 = 1 ORDER BY prod_date DESC;
How does that fare?
If that works standalone, next try that as a literal for your model, this way:
QSqlQueryModel* model = new QSqlQueryModel(this); model->setQuery("SELECT field1, field2, prodCount, field3, prod_date FROM products WHERE 1 = 1 ORDER BY prod_date DESC;");
How does that fare?
-
@snubben said in tableView->setModel(model); causes SIGSEGV.:
it works. It shows the data.
So now per your earlier debug information try the actual query which seems to be executed with your bindings:
SELECT field1, field2, prodCount, field3, prod_date FROM products WHERE 1 = 1 ORDER BY prod_date DESC;
How does that fare?
If that works standalone, next try that as a literal for your model, this way:
QSqlQueryModel* model = new QSqlQueryModel(this); model->setQuery("SELECT field1, field2, prodCount, field3, prod_date FROM products WHERE 1 = 1 ORDER BY prod_date DESC;");
How does that fare?
@JonB said in tableView->setModel(model); causes SIGSEGV.:
@snubben said in tableView->setModel(model); causes SIGSEGV.:
it works. It shows the data.
So now per your earlier debug information try the actual query which seems to be executed with your bindings:
SELECT field1, field2, prodCount, field3, prod_date FROM products WHERE 1 = 1 ORDER BY prod_date DESC;
How does that fare?
If that works standalone, next try that as a literal for your model, this way:
QSqlQueryModel* model = new QSqlQueryModel(this); model->setQuery("SELECT field1, field2, prodCount, field3, prod_date FROM products WHERE 1 = 1 ORDER BY prod_date DESC;");
How does that fare?
Yes, all those work! How to I apply search criterias if I use a QString query?
-
So I debugged some more and if I understand correctly it seg faults in qsql_mysql.cpp at
bool QMYSQLResult::fetch(int i) { Q_D(QMYSQLResult); if (!driver()) return false; if (isForwardOnly()) { // fake a forward seek if (at() < i) { int x = i - at(); while (--x && fetchNext()) {}; return fetchNext(); } else { return false; } } if (at() == i) return true; if (d->preparedQuery) { mysql_stmt_data_seek(d->stmt, i); int nRC = mysql_stmt_fetch(d->stmt); <<<< HERE SEG FAULT if (nRC) { if (nRC == 1 || nRC == MYSQL_DATA_TRUNCATED) setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", "Unable to fetch data"), QSqlError::StatementError, d->stmt)); return false; } } else { mysql_data_seek(d->result, i); d->row = mysql_fetch_row(d->result); if (!d->row) return false; } setAt(i); return true; }
d pointer has the following information:
*d @0x5555557afe10 QMYSQLResultPrivate [QSqlResultPrivate] <not accessible> QSqlResultPrivate fields <5 items> QList<QMYSQLResultPrivate::QMyField> [0] @0x55555573e930 QMYSQLResultPrivate::QMyField bufLength 401 ulong *myField @0x555555929d88 MYSQL_FIELD catalog "def" char * catalog_length 3 unsigned int charsetnr 45 unsigned int db "database_name" char * db_length 9 unsigned int decimals 0 unsigned int def 0x0 char * def_length 0 unsigned int extension 0x0 void * flags 20483 unsigned int length 400 unsigned long max_length 0 unsigned long name "field1" char * name_length 7 unsigned int org_name "field1" char * org_name_length 7 unsigned int org_table "products" char * org_table_length 11 unsigned int table "products" char * table_length 11 unsigned int type MYSQL_TYPE_VAR_STRING (253) enum_field_types nullIndicator 0 my_bool outField "" char * type @0x55555573e940 QMetaType [1] @0x55555573e958 QMYSQLResultPrivate::QMyField bufLength 401 ulong *myField @0x555555929e08 MYSQL_FIELD catalog "def" char * catalog_length 3 unsigned int charsetnr 45 unsigned int db "database_name" char * db_length 9 unsigned int decimals 0 unsigned int def 0x0 char * def_length 0 unsigned int extension 0x0 void * flags 4097 unsigned int length 400 unsigned long max_length 0 unsigned long name "name" char * name_length 4 unsigned int org_name "name" char * org_name_length 4 unsigned int org_table "products" char * org_table_length 11 unsigned int table "products" char * table_length 11 unsigned int type MYSQL_TYPE_VAR_STRING (253) enum_field_types nullIndicator 0 my_bool outField "" char * type @0x55555573e968 QMetaType [2] @0x55555573e980 QMYSQLResultPrivate::QMyField bufLength 4 ulong *myField @0x555555929e88 MYSQL_FIELD catalog "def" char * catalog_length 3 unsigned int charsetnr 63 unsigned int db "database_name" char * db_length 9 unsigned int decimals 0 unsigned int def 0x0 char * def_length 0 unsigned int extension 0x0 void * flags 36865 unsigned int length 11 unsigned long max_length 0 unsigned long name "prodCount" char * name_length 5 unsigned int org_name "prodCount" char * org_name_length 10 unsigned int org_table "products" char * org_table_length 11 unsigned int table "products" char * table_length 11 unsigned int type MYSQL_TYPE_LONG (3) enum_field_types nullIndicator 0 my_bool outField "" char * type @0x55555573e990 QMetaType [3] @0x55555573e9a8 QMYSQLResultPrivate::QMyField bufLength 401 ulong *myField @0x555555929f08 MYSQL_FIELD catalog "def" char * catalog_length 3 unsigned int charsetnr 45 unsigned int db "database_name" char * db_length 9 unsigned int decimals 0 unsigned int def 0x0 char * def_length 0 unsigned int extension 0x0 void * flags 4097 unsigned int length 400 unsigned long max_length 0 unsigned long name "field3" char * name_length 4 unsigned int org_name "field3" char * org_name_length 17 unsigned int org_table "products" char * org_table_length 11 unsigned int table "products" char * table_length 11 unsigned int type MYSQL_TYPE_VAR_STRING (253) enum_field_types nullIndicator 0 my_bool outField "" char * type @0x55555573e9b8 QMetaType [4] @0x55555573e9d0 QMYSQLResultPrivate::QMyField bufLength 40 ulong *myField @0x555555929f88 MYSQL_FIELD catalog "def" char * catalog_length 3 unsigned int charsetnr 63 unsigned int db "database_name" char * db_length 9 unsigned int decimals 0 unsigned int def 0x0 char * def_length 0 unsigned int extension 0x0 void * flags 128 unsigned int length 10 unsigned long max_length 0 unsigned long name "dateMin" char * name_length 8 unsigned int org_name "dateMin" char * org_name_length 8 unsigned int org_table "products" char * org_table_length 11 unsigned int table "products" char * table_length 11 unsigned int type MYSQL_TYPE_DATE (10) enum_field_types nullIndicator 0 my_bool outField "" char * type @0x55555573e9e0 QMetaType hasBlobs false bool *inBinds @0x5555557ce380 MYSQL_BIND buffer 0x5555556f1d30 void * buffer_length 401 unsigned long buffer_type MYSQL_TYPE_STRING (254) enum_field_types error 0x0 my_bool * error_value 0 my_bool extension 0x0 void * fetch_result 0x0 void (st_mysql_bind *, MYSQL_FIELD *, unsigned char * *) * flags 0 unsigned int is_null "" my_bool * is_null_value 0 my_bool is_unsigned 0 my_bool *length 401 unsigned long length_value 0 unsigned long long_data_used 0 my_bool offset 0 unsigned long pack_length 0 unsigned int skip_result 0x0 void (st_mysql_bind *, MYSQL_FIELD *, unsigned char * *) * store_param_func 0x0 void (NET *, st_mysql_bind *) * u @0x5555557ce3a0 union {...} indicator 0x0 char * row_ptr 0x0 unsigned char * *meta @0x5555556eedf0 MYSQL_RES current_field 0 unsigned int current_row 0 MYSQL_ROW data 0x0 MYSQL_DATA * data_cursor 0x0 MYSQL_ROWS * eof 1 my_bool field_alloc @0x5555556eee18 MA_MEM_ROOT field_count 5 unsigned int *fields @0x555555929d88 MYSQL_FIELD handle 0x0 MYSQL * is_ps 0 my_bool lengths 0x0 unsigned long * row 0 MYSQL_ROW row_count 0 unsigned long long outBinds 0x0 MYSQL_BIND * preparedQuery true bool result 0x0 MYSQL_RES * row 0 MYSQL_ROW rowsAffected -1 int *stmt @0x5555556c81a0 MYSQL_STMT array_size 0 unsigned int *bind @0x55555592a198 MYSQL_BIND bind_param_done 0 my_bool bind_result_done 1 my_bool cursor_exists 0 my_bool default_rset_handler 0x7ffff0cf5880 <mysql_next_result+224> mysql_stmt_use_or_store_func execute_count 1 unsigned int extension 0x5555556a9700 void * fetch_row_func 140737233504192 mysql_stmt_fetch_row_func field_count 5 unsigned int *fields @0x555555929d88 MYSQL_FIELD flags 0 unsigned long last_errno 0 unsigned int last_error "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000..." char[513] of length 513 list @0x5555556c84c0 LIST mem_root @0x5555556c81a0 MA_MEM_ROOT *mysql @0x5555556a8280 MYSQL param_callback 0 ps_param_callback param_count 0 unsigned int params 0x0 MYSQL_BIND * prebind_params 0 unsigned int prefetch_rows 1 unsigned long request_buffer 0x0 unsigned char * request_length 0 size_t result @0x5555556c8220 MYSQL_DATA result_callback 0 ps_result_callback *result_cursor @0x55555590fa68 MYSQL_ROWS row_size 0 size_t send_types_to_server '\0' 0 0x00 unsigned char sqlstate "00000\000" char[6] of length 6 state MYSQL_STMT_USER_FETCHING (5) enum_mysqlnd_stmt_state stmt_id 18 unsigned long update_max_length 0 my_bool upsert_status @0x5555556c8290 mysql_upsert_status user_data 0x0 void *
I have anonymized the SQL and database information, therefore the field name lengths do not match.
-
You should really strip this down to a minimal, compileable example. Simply open a db connection, create and fill a table and set the query to the model. Modify it to your use case until it is crashing or you can see what you are doing wrong.
-
So I debugged some more and if I understand correctly it seg faults in qsql_mysql.cpp at
bool QMYSQLResult::fetch(int i) { Q_D(QMYSQLResult); if (!driver()) return false; if (isForwardOnly()) { // fake a forward seek if (at() < i) { int x = i - at(); while (--x && fetchNext()) {}; return fetchNext(); } else { return false; } } if (at() == i) return true; if (d->preparedQuery) { mysql_stmt_data_seek(d->stmt, i); int nRC = mysql_stmt_fetch(d->stmt); <<<< HERE SEG FAULT if (nRC) { if (nRC == 1 || nRC == MYSQL_DATA_TRUNCATED) setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", "Unable to fetch data"), QSqlError::StatementError, d->stmt)); return false; } } else { mysql_data_seek(d->result, i); d->row = mysql_fetch_row(d->result); if (!d->row) return false; } setAt(i); return true; }
d pointer has the following information:
*d @0x5555557afe10 QMYSQLResultPrivate [QSqlResultPrivate] <not accessible> QSqlResultPrivate fields <5 items> QList<QMYSQLResultPrivate::QMyField> [0] @0x55555573e930 QMYSQLResultPrivate::QMyField bufLength 401 ulong *myField @0x555555929d88 MYSQL_FIELD catalog "def" char * catalog_length 3 unsigned int charsetnr 45 unsigned int db "database_name" char * db_length 9 unsigned int decimals 0 unsigned int def 0x0 char * def_length 0 unsigned int extension 0x0 void * flags 20483 unsigned int length 400 unsigned long max_length 0 unsigned long name "field1" char * name_length 7 unsigned int org_name "field1" char * org_name_length 7 unsigned int org_table "products" char * org_table_length 11 unsigned int table "products" char * table_length 11 unsigned int type MYSQL_TYPE_VAR_STRING (253) enum_field_types nullIndicator 0 my_bool outField "" char * type @0x55555573e940 QMetaType [1] @0x55555573e958 QMYSQLResultPrivate::QMyField bufLength 401 ulong *myField @0x555555929e08 MYSQL_FIELD catalog "def" char * catalog_length 3 unsigned int charsetnr 45 unsigned int db "database_name" char * db_length 9 unsigned int decimals 0 unsigned int def 0x0 char * def_length 0 unsigned int extension 0x0 void * flags 4097 unsigned int length 400 unsigned long max_length 0 unsigned long name "name" char * name_length 4 unsigned int org_name "name" char * org_name_length 4 unsigned int org_table "products" char * org_table_length 11 unsigned int table "products" char * table_length 11 unsigned int type MYSQL_TYPE_VAR_STRING (253) enum_field_types nullIndicator 0 my_bool outField "" char * type @0x55555573e968 QMetaType [2] @0x55555573e980 QMYSQLResultPrivate::QMyField bufLength 4 ulong *myField @0x555555929e88 MYSQL_FIELD catalog "def" char * catalog_length 3 unsigned int charsetnr 63 unsigned int db "database_name" char * db_length 9 unsigned int decimals 0 unsigned int def 0x0 char * def_length 0 unsigned int extension 0x0 void * flags 36865 unsigned int length 11 unsigned long max_length 0 unsigned long name "prodCount" char * name_length 5 unsigned int org_name "prodCount" char * org_name_length 10 unsigned int org_table "products" char * org_table_length 11 unsigned int table "products" char * table_length 11 unsigned int type MYSQL_TYPE_LONG (3) enum_field_types nullIndicator 0 my_bool outField "" char * type @0x55555573e990 QMetaType [3] @0x55555573e9a8 QMYSQLResultPrivate::QMyField bufLength 401 ulong *myField @0x555555929f08 MYSQL_FIELD catalog "def" char * catalog_length 3 unsigned int charsetnr 45 unsigned int db "database_name" char * db_length 9 unsigned int decimals 0 unsigned int def 0x0 char * def_length 0 unsigned int extension 0x0 void * flags 4097 unsigned int length 400 unsigned long max_length 0 unsigned long name "field3" char * name_length 4 unsigned int org_name "field3" char * org_name_length 17 unsigned int org_table "products" char * org_table_length 11 unsigned int table "products" char * table_length 11 unsigned int type MYSQL_TYPE_VAR_STRING (253) enum_field_types nullIndicator 0 my_bool outField "" char * type @0x55555573e9b8 QMetaType [4] @0x55555573e9d0 QMYSQLResultPrivate::QMyField bufLength 40 ulong *myField @0x555555929f88 MYSQL_FIELD catalog "def" char * catalog_length 3 unsigned int charsetnr 63 unsigned int db "database_name" char * db_length 9 unsigned int decimals 0 unsigned int def 0x0 char * def_length 0 unsigned int extension 0x0 void * flags 128 unsigned int length 10 unsigned long max_length 0 unsigned long name "dateMin" char * name_length 8 unsigned int org_name "dateMin" char * org_name_length 8 unsigned int org_table "products" char * org_table_length 11 unsigned int table "products" char * table_length 11 unsigned int type MYSQL_TYPE_DATE (10) enum_field_types nullIndicator 0 my_bool outField "" char * type @0x55555573e9e0 QMetaType hasBlobs false bool *inBinds @0x5555557ce380 MYSQL_BIND buffer 0x5555556f1d30 void * buffer_length 401 unsigned long buffer_type MYSQL_TYPE_STRING (254) enum_field_types error 0x0 my_bool * error_value 0 my_bool extension 0x0 void * fetch_result 0x0 void (st_mysql_bind *, MYSQL_FIELD *, unsigned char * *) * flags 0 unsigned int is_null "" my_bool * is_null_value 0 my_bool is_unsigned 0 my_bool *length 401 unsigned long length_value 0 unsigned long long_data_used 0 my_bool offset 0 unsigned long pack_length 0 unsigned int skip_result 0x0 void (st_mysql_bind *, MYSQL_FIELD *, unsigned char * *) * store_param_func 0x0 void (NET *, st_mysql_bind *) * u @0x5555557ce3a0 union {...} indicator 0x0 char * row_ptr 0x0 unsigned char * *meta @0x5555556eedf0 MYSQL_RES current_field 0 unsigned int current_row 0 MYSQL_ROW data 0x0 MYSQL_DATA * data_cursor 0x0 MYSQL_ROWS * eof 1 my_bool field_alloc @0x5555556eee18 MA_MEM_ROOT field_count 5 unsigned int *fields @0x555555929d88 MYSQL_FIELD handle 0x0 MYSQL * is_ps 0 my_bool lengths 0x0 unsigned long * row 0 MYSQL_ROW row_count 0 unsigned long long outBinds 0x0 MYSQL_BIND * preparedQuery true bool result 0x0 MYSQL_RES * row 0 MYSQL_ROW rowsAffected -1 int *stmt @0x5555556c81a0 MYSQL_STMT array_size 0 unsigned int *bind @0x55555592a198 MYSQL_BIND bind_param_done 0 my_bool bind_result_done 1 my_bool cursor_exists 0 my_bool default_rset_handler 0x7ffff0cf5880 <mysql_next_result+224> mysql_stmt_use_or_store_func execute_count 1 unsigned int extension 0x5555556a9700 void * fetch_row_func 140737233504192 mysql_stmt_fetch_row_func field_count 5 unsigned int *fields @0x555555929d88 MYSQL_FIELD flags 0 unsigned long last_errno 0 unsigned int last_error "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000..." char[513] of length 513 list @0x5555556c84c0 LIST mem_root @0x5555556c81a0 MA_MEM_ROOT *mysql @0x5555556a8280 MYSQL param_callback 0 ps_param_callback param_count 0 unsigned int params 0x0 MYSQL_BIND * prebind_params 0 unsigned int prefetch_rows 1 unsigned long request_buffer 0x0 unsigned char * request_length 0 size_t result @0x5555556c8220 MYSQL_DATA result_callback 0 ps_result_callback *result_cursor @0x55555590fa68 MYSQL_ROWS row_size 0 size_t send_types_to_server '\0' 0 0x00 unsigned char sqlstate "00000\000" char[6] of length 6 state MYSQL_STMT_USER_FETCHING (5) enum_mysqlnd_stmt_state stmt_id 18 unsigned long update_max_length 0 my_bool upsert_status @0x5555556c8290 mysql_upsert_status user_data 0x0 void *
I have anonymized the SQL and database information, therefore the field name lengths do not match.
@snubben
As @Christian-Ehrlicher says.Given that you say
QSqlQueryModel* model = new QSqlQueryModel(this); model->setQuery("SELECT field1, field2, prodCount, field3, prod_date FROM products WHERE 1 = 1 ORDER BY prod_date DESC;");
does work I am not sure where your actual example differs significantly from this. Try it now the way you do it as
QSqlQueryModel* model = new QSqlQueryModel(this); QSqlQuery query(db); query.prepare("SELECT field1, field2, prodCount, field3, prod_date FROM products WHERE 1 = 1 ORDER BY prod_date DESC;"); model->setQuery(query);
I have not included your
std::move()
not yourquery.exec();
. Only add those in if it does not work as is. See where you get to. If you get that working I'm sure you can then start introducing parameter bindings.At some point you ought get rid of that
QSqlDatabase db
class member variable. Per the docs you should be using the static QSqlDatabase QSqlDatabase::database() for that instead. I don't know whether it might be relevant here, probably not but you never know. -
S snubben has marked this topic as solved on
-
It works!
QSqlTableModel* model = new QSqlTableModel(this);
Using this it works. I must read more about
QSqlQueryModel
and why it didn't work in this situation.
Thank you all!@snubben said in tableView->setModel(model); causes SIGSEGV.:
Using this it works.
@Christian-Ehrlicher
OP reports thatQSqlTableModel
works for hisQTableView
but notQSqlQueryModel
. I wonder why? QTV only requires aQAbstractItemModel
,QSqlTableModel
inherits fromQSqlQueryModel
, why should the latter not work?The model for QTV must not be forward-only. Is
QSqlQueryModel
perhaps automatically forward-only, is that an issue?UPDATE
Non-issue, see further posts below.