From 3e58f2b090661aab7302132cb2da661c8e227bc2 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 2 Jan 2018 09:33:48 +0100 Subject: 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 --- src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp') diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp index 67dd1a6ee5..444b18686a 100644 --- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp +++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp @@ -446,7 +446,7 @@ static QString timespecToString(const QDateTime &dateTime) bool QSQLiteResult::exec() { Q_D(QSQLiteResult); - const QVector values = boundValues(); + QVector 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 prunedValues; + QList 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 -- cgit v1.2.3