sqlite: Bind duplicated named placeholders correctly
sqlite will reuse the index for bound parameters when the named placeholder is duplicated so we only need to call bind one time for each placeholder. Therefore we need to have just one instance of each value when doing the bind. Task-number: QTBUG-65150 Change-Id: I75c4bcc4563e43c180a59a7a4cbb770dbe994642 Reviewed-by: Jesus Fernandez <Jesus.Fernandez@qt.io>
This commit is contained in:
parent
24fba6744c
commit
3e58f2b090
@ -446,7 +446,7 @@ static QString timespecToString(const QDateTime &dateTime)
|
||||
bool QSQLiteResult::exec()
|
||||
{
|
||||
Q_D(QSQLiteResult);
|
||||
const QVector<QVariant> values = boundValues();
|
||||
QVector<QVariant> values = boundValues();
|
||||
|
||||
d->skippedStatus = false;
|
||||
d->skipRow = false;
|
||||
@ -478,6 +478,20 @@ bool QSQLiteResult::exec()
|
||||
countIndexes);
|
||||
|
||||
paramCountIsValid = bindParamCount == values.count();
|
||||
// When using named placeholders, it will reuse the index for duplicated
|
||||
// placeholders. So we need to ensure the QVector has only one instance of
|
||||
// each value as SQLite will do the rest for us.
|
||||
QVector<QVariant> prunedValues;
|
||||
QList<int> handledIndexes;
|
||||
for (int i = 0, currentIndex = 0; i < values.size(); ++i) {
|
||||
if (handledIndexes.contains(i))
|
||||
continue;
|
||||
const auto placeHolder = QString::fromUtf8(sqlite3_bind_parameter_name(d->stmt, currentIndex + 1));
|
||||
handledIndexes << d->indexes[placeHolder];
|
||||
prunedValues << values.at(d->indexes[placeHolder].first());
|
||||
++currentIndex;
|
||||
}
|
||||
values = prunedValues;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2017,6 +2017,31 @@ void tst_QSqlQuery::prepare_bind_exec()
|
||||
QCOMPARE( q.value(1).toString(), QString("name") );
|
||||
QCOMPARE( q.value(2).toString(), QString("name") );
|
||||
|
||||
// Test that duplicated named placeholders before the next unique one works correctly - QTBUG-65150
|
||||
QVERIFY(q.prepare("insert into " + qtest_prepare + " (id, name, name2) values (:id, :id, :name)"));
|
||||
for (i = 104; i < 106; ++i) {
|
||||
q.bindValue(":id", i);
|
||||
q.bindValue(":name", "name");
|
||||
QVERIFY(q.exec());
|
||||
}
|
||||
QVERIFY(q.exec("select * from " + qtest_prepare + " where id > 103 order by id"));
|
||||
QVERIFY(q.next());
|
||||
QCOMPARE(q.value(0).toInt(), 104);
|
||||
QCOMPARE(q.value(1).toString(), QString("104"));
|
||||
QCOMPARE(q.value(2).toString(), QString("name"));
|
||||
|
||||
// Test that duplicated named placeholders in any order
|
||||
QVERIFY(q.prepare("insert into " + qtest_prepare + " (id, name, name2) values (:id, :name, :id)"));
|
||||
for (i = 107; i < 109; ++i) {
|
||||
q.bindValue(":id", i);
|
||||
q.bindValue(":name", "name");
|
||||
QVERIFY(q.exec());
|
||||
}
|
||||
QVERIFY(q.exec("select * from " + qtest_prepare + " where id > 106 order by id"));
|
||||
QVERIFY(q.next());
|
||||
QCOMPARE(q.value(0).toInt(), 107);
|
||||
QCOMPARE(q.value(1).toString(), QString("name"));
|
||||
QCOMPARE(q.value(2).toString(), QString("107"));
|
||||
} // end of SQLite scope
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user