diff options
author | Israel Lins Albuquerque <israel@proabakus.com.br> | 2013-11-04 19:45:28 -0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-12-16 15:35:30 +0100 |
commit | 5193c14536fafc57c860e9e234e21ddc29d5b6b0 (patch) | |
tree | 4a0b6c67ba2d5ffb793bc87ebd8d6ff0ce7a39e8 | |
parent | b3b689edcb2441051fc3d4fee006c41eb918730b (diff) |
fix parsing of bound SQL statements for PostgreSQL
PostgreSQL allows bound variables inside square braces.
Task-number: QTBUG-34541
Change-Id: I4f069b3f1078d4cdf172fbac9e0d7d23d20d167a
Reviewed-by: Mark Brand <mabrand@mabrand.nl>
-rw-r--r-- | src/sql/kernel/qsqldriver.h | 1 | ||||
-rw-r--r-- | src/sql/kernel/qsqlresult.cpp | 7 | ||||
-rw-r--r-- | tests/auto/sql/kernel/qsqlresult/qsqlresult.pro | 2 | ||||
-rw-r--r-- | tests/auto/sql/kernel/qsqlresult/testsqldriver.h | 9 | ||||
-rw-r--r-- | tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp | 20 |
5 files changed, 32 insertions, 7 deletions
diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h index 017ffd4e4a..f93a03063b 100644 --- a/src/sql/kernel/qsqldriver.h +++ b/src/sql/kernel/qsqldriver.h @@ -62,6 +62,7 @@ class QVariant; class Q_SQL_EXPORT QSqlDriver : public QObject { friend class QSqlDatabase; + friend class QSqlResultPrivate; Q_OBJECT Q_DECLARE_PRIVATE(QSqlDriver) diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 953e2ca66e..31b05ab9e9 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -51,6 +51,7 @@ #include "qsqldriver.h" #include "qpointer.h" #include "qsqlresult_p.h" +#include "private/qsqldriver_p.h" #include <QDebug> QT_BEGIN_NAMESPACE @@ -89,6 +90,7 @@ QString QSqlResultPrivate::positionalToNamedBinding(const QString &query) const result.reserve(n * 5 / 4); QChar closingQuote; int count = 0; + bool ignoreBraces = (sqldriver->d_func()->dbmsType == QSqlDriverPrivate::PostgreSQL); for (int i = 0; i < n; ++i) { QChar ch = query.at(i); @@ -110,7 +112,7 @@ QString QSqlResultPrivate::positionalToNamedBinding(const QString &query) const } else { if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`')) closingQuote = ch; - else if (ch == QLatin1Char('[')) + else if (!ignoreBraces && ch == QLatin1Char('[')) closingQuote = QLatin1Char(']'); result += ch; } @@ -129,6 +131,7 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query) QChar closingQuote; int count = 0; int i = 0; + bool ignoreBraces = (sqldriver->d_func()->dbmsType == QSqlDriverPrivate::PostgreSQL); while (i < n) { QChar ch = query.at(i); @@ -160,7 +163,7 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query) } else { if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`')) closingQuote = ch; - else if (ch == QLatin1Char('[')) + else if (!ignoreBraces && ch == QLatin1Char('[')) closingQuote = QLatin1Char(']'); result += ch; ++i; diff --git a/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro b/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro index ef6c7a7e09..114327effb 100644 --- a/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro +++ b/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro @@ -1,7 +1,7 @@ TARGET = tst_qsqlresult CONFIG += testcase -QT = core sql testlib +QT = core core-private sql sql-private testlib SOURCES += tst_qsqlresult.cpp HEADERS += testsqldriver.h diff --git a/tests/auto/sql/kernel/qsqlresult/testsqldriver.h b/tests/auto/sql/kernel/qsqlresult/testsqldriver.h index 9d435a0f7c..eda0658b41 100644 --- a/tests/auto/sql/kernel/qsqlresult/testsqldriver.h +++ b/tests/auto/sql/kernel/qsqlresult/testsqldriver.h @@ -45,6 +45,7 @@ #include <QtSql/QSqlResult> #include <QtSql/QSqlDriver> #include <QtSql/QSqlRecord> +#include <private/qsqldriver_p.h> class TestSqlDriverResult : public QSqlResult { @@ -77,6 +78,8 @@ protected: class TestSqlDriver : public QSqlDriver { + Q_DECLARE_PRIVATE(QSqlDriver) + public: TestSqlDriver() {} ~TestSqlDriver() {} @@ -96,6 +99,12 @@ public: int /* port */, const QString & /* options */) { return false; } void close() {} + QSqlDriverPrivate::DBMSType dbmsType() const + { + Q_D(const QSqlDriver); + return d->dbmsType; + } + QSqlResult *createResult() const { return new TestSqlDriverResult(this); } }; diff --git a/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp b/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp index ba6b4d1fbf..2462fab879 100644 --- a/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp +++ b/tests/auto/sql/kernel/qsqlresult/tst_qsqlresult.cpp @@ -79,18 +79,30 @@ void tst_QSqlResult::parseOfBoundValues() QVERIFY(result.savePrepare("SELECT :1 AS ':2'")); QCOMPARE(result.boundValues().count(), 1); QVERIFY(result.savePrepare("SELECT :1 AS [:2]")); - QCOMPARE(result.boundValues().count(), 1); + if (testDriver.dbmsType() == QSqlDriverPrivate::PostgreSQL) + QCOMPARE(result.boundValues().count(), 2); + else + QCOMPARE(result.boundValues().count(), 1); QVERIFY(result.savePrepare("SELECT :1 AS [:2]]]")); - QCOMPARE(result.boundValues().count(), 1); + if (testDriver.dbmsType() == QSqlDriverPrivate::PostgreSQL) + QCOMPARE(result.boundValues().count(), 2); + else + QCOMPARE(result.boundValues().count(), 1); QVERIFY(result.savePrepare("SELECT :1 AS [:2]]]]]")); - QCOMPARE(result.boundValues().count(), 1); + if (testDriver.dbmsType() == QSqlDriverPrivate::PostgreSQL) + QCOMPARE(result.boundValues().count(), 2); + else + QCOMPARE(result.boundValues().count(), 1); QVERIFY(result.savePrepare("SELECT ? AS \"?\"")); QCOMPARE(result.boundValues().count(), 1); QVERIFY(result.savePrepare("SELECT ? AS '?'")); QCOMPARE(result.boundValues().count(), 1); QVERIFY(result.savePrepare("SELECT ? AS [?]")); - QCOMPARE(result.boundValues().count(), 1); + if (testDriver.dbmsType() == QSqlDriverPrivate::PostgreSQL) + QCOMPARE(result.boundValues().count(), 2); + else + QCOMPARE(result.boundValues().count(), 1); QVERIFY(result.savePrepare("SELECT ? AS \"'?\"")); QCOMPARE(result.boundValues().count(), 1); |