postgresql driver: escape backslashes only when server requires it

Task-number: QTBUG-30076

Change-Id: I408cda941884f01484d0edfa82c91fc19cb8718c
Reviewed-by: Israel Lins Albuquerque <israelins85@yahoo.com.br>
Reviewed-by: Sergey Blagodarin
Reviewed-by: Andy Shaw <andy.shaw@digia.com>
Reviewed-by: Andras Mantia <andras@kdab.com>
bb10
Mark Brand 2013-03-07 11:52:52 +01:00 committed by The Qt Project
parent 36b6d4afc9
commit e3c5351d06
1 changed files with 33 additions and 5 deletions

View File

@ -124,7 +124,16 @@ inline void qPQfreemem(void *buffer)
class QPSQLDriverPrivate
{
public:
QPSQLDriverPrivate(QPSQLDriver *qq) : q(qq), connection(0), isUtf8(false), pro(QPSQLDriver::Version6), sn(0), pendingNotifyCheck(false) {}
QPSQLDriverPrivate(QPSQLDriver *qq)
: q(qq),
connection(0),
isUtf8(false),
pro(QPSQLDriver::Version6),
sn(0),
pendingNotifyCheck(false),
hasBackslashEscape(false)
{ }
QPSQLDriver *q;
PGconn *connection;
bool isUtf8;
@ -132,6 +141,7 @@ public:
QSocketNotifier *sn;
QStringList seid;
mutable bool pendingNotifyCheck;
bool hasBackslashEscape;
void appendTables(QStringList &tl, QSqlQuery &t, QChar type);
PGresult * exec(const char * stmt) const;
@ -139,6 +149,7 @@ public:
QPSQLDriver::Protocol getPSQLVersion();
bool setEncodingUtf8();
void setDatestyle();
void detectBackslashEscape();
};
void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type)
@ -615,6 +626,23 @@ void QPSQLDriverPrivate::setDatestyle()
PQclear(result);
}
void QPSQLDriverPrivate::detectBackslashEscape()
{
// standard_conforming_strings option introduced in 8.2
// http://www.postgresql.org/docs/8.2/static/runtime-config-compatible.html
if (pro < QPSQLDriver::Version82) {
hasBackslashEscape = true;
} else {
hasBackslashEscape = false;
PGresult* result = exec(QLatin1Literal("SELECT '\\\\' x"));
int status = PQresultStatus(result);
if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK)
if (QString::fromLatin1(PQgetvalue(result, 0, 0)) == QLatin1Literal("\\"))
hasBackslashEscape = true;
PQclear(result);
}
}
static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin)
{
switch (vMaj) {
@ -726,6 +754,7 @@ QPSQLDriver::QPSQLDriver(PGconn *conn, QObject *parent)
d->connection = conn;
if (conn) {
d->pro = d->getPSQLVersion();
d->detectBackslashEscape();
setOpen(true);
setOpenError(false);
}
@ -827,6 +856,7 @@ bool QPSQLDriver::open(const QString & db,
}
d->pro = d->getPSQLVersion();
d->detectBackslashEscape();
d->isUtf8 = d->setEncodingUtf8();
d->setDatestyle();
@ -1212,12 +1242,10 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
}
break;
case QVariant::String:
{
// Escape '\' characters
r = QSqlDriver::formatValue(field, trimStrings);
r.replace(QLatin1String("\\"), QLatin1String("\\\\"));
if (d->hasBackslashEscape)
r.replace(QLatin1String("\\"), QLatin1String("\\\\"));
break;
}
case QVariant::Bool:
if (field.value().toBool())
r = QLatin1String("TRUE");