From 65afcef2173cabe297778d19dda3198595820cfa Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Sat, 8 Aug 2020 23:14:13 +0200 Subject: Interbase: Handle EXECUTE BLOCK statements correctly Since an EXECUTE BLOCK statement can have a mix of ? and :var syntax then a special case for this needs to be added so that it does not try to convert the :var parts into positional placeholders as they need to kept as-is when preparing such a statement. Pick-to: 5.15 Fixes: QTBUG-83152 Change-Id: Iff891207ad6dea1681a1b3a335acbbbb668b465d Reviewed-by: Christian Ehrlicher --- src/sql/kernel/qsqlresult.cpp | 7 +++++++ tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 24ca1ffeda..5b440d704b 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -112,6 +112,13 @@ QString QSqlResultPrivate::positionalToNamedBinding(const QString &query) const QString QSqlResultPrivate::namedToPositionalBinding(const QString &query) { + // In the Interbase case if it is an EXECUTE BLOCK then it is up to the + // caller to make sure that it is not using named bindings for the wrong + // parts of the query since Interbase uses them literally + if (sqldriver->dbmsType() == QSqlDriver::Interbase && + query.trimmed().startsWith(QLatin1String("EXECUTE BLOCK"), Qt::CaseInsensitive)) + return query; + int n = query.size(); QString result; diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 30c2f9ac62..322c1b3b84 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -184,6 +184,8 @@ private slots: void sqliteVirtualTable(); void mysql_timeType_data() { generic_data("QMYSQL"); } void mysql_timeType(); + void ibase_executeBlock_data() { generic_data("QIBASE"); } + void ibase_executeBlock(); void task_217003_data() { generic_data(); } void task_217003(); @@ -4797,5 +4799,25 @@ void tst_QSqlQuery::ibaseArray() QCOMPARE(qry.value(3).toList(), boolArray.toList()); } +void tst_QSqlQuery::ibase_executeBlock() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + QSqlQuery qry(db); + QVERIFY_SQL(qry, prepare("execute block (x double precision = ?, y double precision = ?) " + "returns (total double precision) " + "as " + "begin " + "total = :x + :y; " + "suspend; " + "end")); + qry.bindValue(0, 2); + qry.bindValue(1, 2); + QVERIFY_SQL(qry, exec()); + QVERIFY(qry.next()); + QCOMPARE(qry.value(0).toInt(), 4); +} + QTEST_MAIN( tst_QSqlQuery ) #include "tst_qsqlquery.moc" -- cgit v1.2.3