psql: do not try to get table name when PQftable returns InvalidOid

When the table for a selected column can't be determined (e.g. because
there is no table for it), PQftable returns InvalidOid. This was not
covered and a query to determine the table name was executed every
time which slowed down calls to QSqlQuery::value(QString).

Task-number: QTBUG-65226
Change-Id: Idd8fbaaef7b01ca4151439f46cad2cce6f1c93e9
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
Christian Ehrlicher 2018-02-15 21:34:50 +01:00
parent 988c3e4fc0
commit a924b4d58f
2 changed files with 42 additions and 7 deletions

View File

@ -817,19 +817,21 @@ QSqlRecord QPSQLResult::record() const
else
f.setName(QString::fromLocal8Bit(PQfname(d->result, i)));
const int tableOid = PQftable(d->result, i);
auto &tableName = d->drv_d_func()->oidToTable[tableOid];
// WARNING: We cannot execute any other SQL queries on
// the same db connection while forward-only mode is active
// (this would discard all results of forward-only query).
// So we just skip this...
if (tableName.isEmpty() && !isForwardOnly()) {
QSqlQuery qry(driver()->createResult());
if (qry.exec(QStringLiteral("SELECT relname FROM pg_class WHERE pg_class.oid = %1")
.arg(tableOid)) && qry.next()) {
tableName = qry.value(0).toString();
if (tableOid != InvalidOid && !isForwardOnly()) {
auto &tableName = d->drv_d_func()->oidToTable[tableOid];
if (tableName.isEmpty()) {
QSqlQuery qry(driver()->createResult());
if (qry.exec(QStringLiteral("SELECT relname FROM pg_class WHERE pg_class.oid = %1")
.arg(tableOid)) && qry.next()) {
tableName = qry.value(0).toString();
}
}
f.setTableName(tableName);
}
f.setTableName(tableName);
int ptype = PQftype(d->result, i);
f.setType(qDecodePSQLType(ptype));
int len = PQfsize(d->result, i);

View File

@ -50,6 +50,10 @@ public slots:
private slots:
void benchmarkRecord_data() { generic_data(); }
void benchmarkRecord();
void benchFieldName_data() { generic_data(); }
void benchFieldName();
void benchFieldIndex_data() { generic_data(); }
void benchFieldIndex();
private:
void generic_data(const QString &engine = QString());
@ -188,4 +192,33 @@ void tst_QSqlRecord::benchmarkRecord()
tst_Databases::safeDropTables(db, QStringList() << tableName);
}
void tst_QSqlRecord::benchFieldName()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) {
QSqlQuery qry(db);
QVERIFY_SQL(qry, exec("SELECT GENERATE_SERIES(1,5000) AS r"));
QBENCHMARK {
while (qry.next())
qry.value("r");
}
}
}
void tst_QSqlRecord::benchFieldIndex()
{
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) {
QSqlQuery qry(db);
QVERIFY_SQL(qry, exec("SELECT GENERATE_SERIES(1,5000) AS r"));
qry = db.exec("SELECT GENERATE_SERIES(1,5000) AS r");
QBENCHMARK {
while (qry.next())
qry.value(0);
}
}
}
#include "tst_qsqlrecord.moc"