QPSQL: Fix handling binary data for PostgreSQL 9.x and later

Set byte_output to 'escape' mode for server version 9 and later,
no matter what version of client library we use.
Since setting byte_output doesn't depend on client version anymore,
we can move it to separate function.

This fixes qtbase\tests\auto\sql\kernel\qsqldatabase
tst_QSqlDatabase::psql_escapeBytea() test
(before this change test did not pass on PostgreSQL 9.6)

Change-Id: I37aaa18267d7e6459c00010ed899536c01e8124e
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
bb10
Robert Szefner 2017-10-20 23:31:12 +02:00 committed by Robert Szefner
parent 435c4b2ccb
commit ff914ea59c
1 changed files with 17 additions and 8 deletions

View File

@ -181,6 +181,7 @@ public:
QPSQLDriver::Protocol getPSQLVersion();
bool setEncodingUtf8();
void setDatestyle();
void setByteaOutput();
void detectBackslashEscape();
};
@ -693,6 +694,20 @@ void QPSQLDriverPrivate::setDatestyle()
PQclear(result);
}
void QPSQLDriverPrivate::setByteaOutput()
{
if (pro >= QPSQLDriver::Version9) {
// Server version before QPSQLDriver::Version9 only supports escape mode for bytea type,
// but bytea format is set to hex by default in PSQL 9 and above. So need to force the
// server to use the old escape mode when connects to the new server.
PGresult *result = exec("SET bytea_output TO escape");
int status = PQresultStatus(result);
if (status != PGRES_COMMAND_OK)
qWarning("%s", PQerrorMessage(connection));
PQclear(result);
}
}
void QPSQLDriverPrivate::detectBackslashEscape()
{
// standard_conforming_strings option introduced in 8.2
@ -818,14 +833,7 @@ QPSQLDriver::Protocol QPSQLDriverPrivate::getPSQLVersion()
QPSQLDriver::VersionUnknown;
#endif
if (serverVersion >= QPSQLDriver::Version9 && clientVersion < QPSQLDriver::Version9) {
// Client version before QPSQLDriver::Version9 only supports escape mode for bytea type,
// but bytea format is set to hex by default in PSQL 9 and above. So need to force the
// server use the old escape mode when connects to the new server with old client library.
result = exec("SET bytea_output=escape; ");
status = PQresultStatus(result);
PQclear(result);
} else if (serverVersion == QPSQLDriver::VersionUnknown) {
if (serverVersion == QPSQLDriver::VersionUnknown) {
serverVersion = clientVersion;
if (serverVersion != QPSQLDriver::VersionUnknown)
qWarning("The server version of this PostgreSQL is unknown, falling back to the client version.");
@ -957,6 +965,7 @@ bool QPSQLDriver::open(const QString & db,
d->detectBackslashEscape();
d->isUtf8 = d->setEncodingUtf8();
d->setDatestyle();
d->setByteaOutput();
setOpen(true);
setOpenError(false);