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>
This commit is contained in:
parent
b3b689edcb
commit
5193c14536
@ -62,6 +62,7 @@ class QVariant;
|
|||||||
class Q_SQL_EXPORT QSqlDriver : public QObject
|
class Q_SQL_EXPORT QSqlDriver : public QObject
|
||||||
{
|
{
|
||||||
friend class QSqlDatabase;
|
friend class QSqlDatabase;
|
||||||
|
friend class QSqlResultPrivate;
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DECLARE_PRIVATE(QSqlDriver)
|
Q_DECLARE_PRIVATE(QSqlDriver)
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "qsqldriver.h"
|
#include "qsqldriver.h"
|
||||||
#include "qpointer.h"
|
#include "qpointer.h"
|
||||||
#include "qsqlresult_p.h"
|
#include "qsqlresult_p.h"
|
||||||
|
#include "private/qsqldriver_p.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -89,6 +90,7 @@ QString QSqlResultPrivate::positionalToNamedBinding(const QString &query) const
|
|||||||
result.reserve(n * 5 / 4);
|
result.reserve(n * 5 / 4);
|
||||||
QChar closingQuote;
|
QChar closingQuote;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
bool ignoreBraces = (sqldriver->d_func()->dbmsType == QSqlDriverPrivate::PostgreSQL);
|
||||||
|
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
QChar ch = query.at(i);
|
QChar ch = query.at(i);
|
||||||
@ -110,7 +112,7 @@ QString QSqlResultPrivate::positionalToNamedBinding(const QString &query) const
|
|||||||
} else {
|
} else {
|
||||||
if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`'))
|
if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`'))
|
||||||
closingQuote = ch;
|
closingQuote = ch;
|
||||||
else if (ch == QLatin1Char('['))
|
else if (!ignoreBraces && ch == QLatin1Char('['))
|
||||||
closingQuote = QLatin1Char(']');
|
closingQuote = QLatin1Char(']');
|
||||||
result += ch;
|
result += ch;
|
||||||
}
|
}
|
||||||
@ -129,6 +131,7 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query)
|
|||||||
QChar closingQuote;
|
QChar closingQuote;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
bool ignoreBraces = (sqldriver->d_func()->dbmsType == QSqlDriverPrivate::PostgreSQL);
|
||||||
|
|
||||||
while (i < n) {
|
while (i < n) {
|
||||||
QChar ch = query.at(i);
|
QChar ch = query.at(i);
|
||||||
@ -160,7 +163,7 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query)
|
|||||||
} else {
|
} else {
|
||||||
if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`'))
|
if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`'))
|
||||||
closingQuote = ch;
|
closingQuote = ch;
|
||||||
else if (ch == QLatin1Char('['))
|
else if (!ignoreBraces && ch == QLatin1Char('['))
|
||||||
closingQuote = QLatin1Char(']');
|
closingQuote = QLatin1Char(']');
|
||||||
result += ch;
|
result += ch;
|
||||||
++i;
|
++i;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
TARGET = tst_qsqlresult
|
TARGET = tst_qsqlresult
|
||||||
CONFIG += testcase
|
CONFIG += testcase
|
||||||
|
|
||||||
QT = core sql testlib
|
QT = core core-private sql sql-private testlib
|
||||||
|
|
||||||
SOURCES += tst_qsqlresult.cpp
|
SOURCES += tst_qsqlresult.cpp
|
||||||
HEADERS += testsqldriver.h
|
HEADERS += testsqldriver.h
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include <QtSql/QSqlResult>
|
#include <QtSql/QSqlResult>
|
||||||
#include <QtSql/QSqlDriver>
|
#include <QtSql/QSqlDriver>
|
||||||
#include <QtSql/QSqlRecord>
|
#include <QtSql/QSqlRecord>
|
||||||
|
#include <private/qsqldriver_p.h>
|
||||||
|
|
||||||
class TestSqlDriverResult : public QSqlResult
|
class TestSqlDriverResult : public QSqlResult
|
||||||
{
|
{
|
||||||
@ -77,6 +78,8 @@ protected:
|
|||||||
|
|
||||||
class TestSqlDriver : public QSqlDriver
|
class TestSqlDriver : public QSqlDriver
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PRIVATE(QSqlDriver)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TestSqlDriver() {}
|
TestSqlDriver() {}
|
||||||
~TestSqlDriver() {}
|
~TestSqlDriver() {}
|
||||||
@ -96,6 +99,12 @@ public:
|
|||||||
int /* port */, const QString & /* options */)
|
int /* port */, const QString & /* options */)
|
||||||
{ return false; }
|
{ return false; }
|
||||||
void close() {}
|
void close() {}
|
||||||
|
QSqlDriverPrivate::DBMSType dbmsType() const
|
||||||
|
{
|
||||||
|
Q_D(const QSqlDriver);
|
||||||
|
return d->dbmsType;
|
||||||
|
}
|
||||||
|
|
||||||
QSqlResult *createResult() const { return new TestSqlDriverResult(this); }
|
QSqlResult *createResult() const { return new TestSqlDriverResult(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,18 +79,30 @@ void tst_QSqlResult::parseOfBoundValues()
|
|||||||
QVERIFY(result.savePrepare("SELECT :1 AS ':2'"));
|
QVERIFY(result.savePrepare("SELECT :1 AS ':2'"));
|
||||||
QCOMPARE(result.boundValues().count(), 1);
|
QCOMPARE(result.boundValues().count(), 1);
|
||||||
QVERIFY(result.savePrepare("SELECT :1 AS [:2]"));
|
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]]]"));
|
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]]]]]"));
|
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 \"?\""));
|
QVERIFY(result.savePrepare("SELECT ? AS \"?\""));
|
||||||
QCOMPARE(result.boundValues().count(), 1);
|
QCOMPARE(result.boundValues().count(), 1);
|
||||||
QVERIFY(result.savePrepare("SELECT ? AS '?'"));
|
QVERIFY(result.savePrepare("SELECT ? AS '?'"));
|
||||||
QCOMPARE(result.boundValues().count(), 1);
|
QCOMPARE(result.boundValues().count(), 1);
|
||||||
QVERIFY(result.savePrepare("SELECT ? AS [?]"));
|
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 \"'?\""));
|
QVERIFY(result.savePrepare("SELECT ? AS \"'?\""));
|
||||||
QCOMPARE(result.boundValues().count(), 1);
|
QCOMPARE(result.boundValues().count(), 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user