diff options
author | Liang Qi <liang.qi@qt.io> | 2017-11-09 11:05:03 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-11-09 11:47:57 +0100 |
commit | 88cf04458002d863750e9121af7dcd9bcbfaa169 (patch) | |
tree | caccae211eef1a27fa5caae3a8403830b615bd5e /src/plugins/sqldrivers | |
parent | 19b0ce5daa31e2ffebfcf2701143742302f1deb4 (diff) | |
parent | 579d0cb2bed193ccb1901b121a360f85d1c57a54 (diff) |
Merge remote-tracking branch 'origin/5.9' into 5.10
Conflicts:
src/gui/kernel/qwindow.cpp
src/plugins/platforms/cocoa/qcocoawindow.mm
src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
tests/auto/widgets/kernel/qaction/tst_qaction.cpp
Change-Id: Ifa515dc0ece7eb1471b00c1214149629a7e6a233
Diffstat (limited to 'src/plugins/sqldrivers')
-rw-r--r-- | src/plugins/sqldrivers/psql/qsql_psql.cpp | 191 | ||||
-rw-r--r-- | src/plugins/sqldrivers/psql/qsql_psql_p.h | 24 |
2 files changed, 117 insertions, 98 deletions
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index a3aa0f6593..0f4b7a80af 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -181,13 +181,14 @@ public: QPSQLDriver::Protocol getPSQLVersion(); bool setEncodingUtf8(); void setDatestyle(); + void setByteaOutput(); void detectBackslashEscape(); }; void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type) { QString query; - if (pro >= QPSQLDriver::Version73) { + if (pro >= QPSQLDriver::Version7_3) { query = QString::fromLatin1("select pg_class.relname, pg_namespace.nspname from pg_class " "left join pg_namespace on (pg_class.relnamespace = pg_namespace.oid) " "where (pg_class.relkind = '%1') and (pg_class.relname !~ '^Inv') " @@ -525,7 +526,7 @@ int QPSQLResult::numRowsAffected() QVariant QPSQLResult::lastInsertId() const { Q_D(const QPSQLResult); - if (d->drv_d_func()->pro >= QPSQLDriver::Version81) { + if (d->drv_d_func()->pro >= QPSQLDriver::Version8_1) { QSqlQuery qry(driver()->createResult()); // Most recent sequence value obtained from nextval if (qry.exec(QLatin1String("SELECT lastval();")) && qry.next()) @@ -698,11 +699,25 @@ 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 // http://www.postgresql.org/docs/8.2/static/runtime-config-compatible.html - if (pro < QPSQLDriver::Version82) { + if (pro < QPSQLDriver::Version8_2) { hasBackslashEscape = true; } else { hasBackslashEscape = false; @@ -724,11 +739,11 @@ static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin) { switch (vMin) { case 1: - return QPSQLDriver::Version71; + return QPSQLDriver::Version7_1; case 3: - return QPSQLDriver::Version73; + return QPSQLDriver::Version7_3; case 4: - return QPSQLDriver::Version74; + return QPSQLDriver::Version7_4; default: return QPSQLDriver::Version7; } @@ -738,76 +753,102 @@ static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin) { switch (vMin) { case 1: - return QPSQLDriver::Version81; + return QPSQLDriver::Version8_1; case 2: - return QPSQLDriver::Version82; + return QPSQLDriver::Version8_2; case 3: - return QPSQLDriver::Version83; + return QPSQLDriver::Version8_3; case 4: - return QPSQLDriver::Version84; + return QPSQLDriver::Version8_4; default: return QPSQLDriver::Version8; } break; } case 9: - return QPSQLDriver::Version9; + { + switch (vMin) { + case 1: + return QPSQLDriver::Version9_1; + case 2: + return QPSQLDriver::Version9_2; + case 3: + return QPSQLDriver::Version9_3; + case 4: + return QPSQLDriver::Version9_4; + case 5: + return QPSQLDriver::Version9_5; + case 6: + return QPSQLDriver::Version9_6; + default: + return QPSQLDriver::Version9; + } break; + } + case 10: + return QPSQLDriver::Version10; default: + if (vMaj > 10) + return QPSQLDriver::UnknownLaterVersion; break; } return QPSQLDriver::VersionUnknown; } +static QPSQLDriver::Protocol qFindPSQLVersion(const QString &versionString) +{ + const QRegExp rx(QStringLiteral("(\\d+)(?:\\.(\\d+))?")); + if (rx.indexIn(versionString) != -1) { + // Beginning with PostgreSQL version 10, a major release is indicated by + // increasing the first part of the version, e.g. 10 to 11. + // Before version 10, a major release was indicated by increasing either + // the first or second part of the version number, e.g. 9.5 to 9.6. + int vMaj = rx.cap(1).toInt(); + int vMin; + if (vMaj >= 10) { + vMin = 0; + } else { + if (rx.cap(2).isEmpty()) + return QPSQLDriver::VersionUnknown; + vMin = rx.cap(2).toInt(); + } + return qMakePSQLVersion(vMaj, vMin); + } + + return QPSQLDriver::VersionUnknown; +} + QPSQLDriver::Protocol QPSQLDriverPrivate::getPSQLVersion() { QPSQLDriver::Protocol serverVersion = QPSQLDriver::Version6; PGresult* result = exec("select version()"); int status = PQresultStatus(result); if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) { - QString val = QString::fromLatin1(PQgetvalue(result, 0, 0)); - - QRegExp rx(QLatin1String("(\\d+)\\.(\\d+)")); - rx.setMinimal(true); // enforce non-greedy RegExp + serverVersion = qFindPSQLVersion( + QString::fromLatin1(PQgetvalue(result, 0, 0))); + } + PQclear(result); - if (rx.indexIn(val) != -1) { - int vMaj = rx.cap(1).toInt(); - int vMin = rx.cap(2).toInt(); - serverVersion = qMakePSQLVersion(vMaj, vMin); + QPSQLDriver::Protocol clientVersion = #if defined(PG_MAJORVERSION) - if (rx.indexIn(QLatin1String(PG_MAJORVERSION)) != -1) + qFindPSQLVersion(QLatin1String(PG_MAJORVERSION)); #elif defined(PG_VERSION) - if (rx.indexIn(QLatin1String(PG_VERSION)) != -1) + qFindPSQLVersion(QLatin1String(PG_VERSION)); #else - if (0) + QPSQLDriver::VersionUnknown; #endif - { - vMaj = rx.cap(1).toInt(); - vMin = rx.cap(2).toInt(); - QPSQLDriver::Protocol clientVersion = qMakePSQLVersion(vMaj, vMin); - - 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. - PQclear(result); - result = exec("SET bytea_output=escape; "); - status = PQresultStatus(result); - } else 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."); - } - } - } + + 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."); } - PQclear(result); - //keep the old behavior unchanged + // Keep the old behavior unchanged if (serverVersion == QPSQLDriver::VersionUnknown) serverVersion = QPSQLDriver::Version6; - if (serverVersion < QPSQLDriver::Version71) { + if (serverVersion < QPSQLDriver::Version7_3) { qWarning("This version of PostgreSQL is not supported and may not work."); } @@ -857,7 +898,7 @@ bool QPSQLDriver::hasFeature(DriverFeature f) const return true; case PreparedQueries: case PositionalPlaceholders: - return d->pro >= QPSQLDriver::Version82; + return d->pro >= QPSQLDriver::Version8_2; case BatchOperations: case NamedPlaceholders: case SimpleLocking: @@ -866,7 +907,7 @@ bool QPSQLDriver::hasFeature(DriverFeature f) const case CancelQuery: return false; case BLOB: - return d->pro >= QPSQLDriver::Version71; + return d->pro >= QPSQLDriver::Version7_1; case Unicode: return d->isUtf8; } @@ -929,6 +970,7 @@ bool QPSQLDriver::open(const QString & db, d->detectBackslashEscape(); d->isUtf8 = d->setEncodingUtf8(); d->setDatestyle(); + d->setByteaOutput(); setOpen(true); setOpenError(false); @@ -993,12 +1035,7 @@ bool QPSQLDriver::commitTransaction() // This hack is used to tell if the transaction has succeeded for the protocol versions of // PostgreSQL below. For 7.x and other protocol versions we are left in the dark. // This hack can dissapear once there is an API to query this sort of information. - if (d->pro == QPSQLDriver::Version8 || - d->pro == QPSQLDriver::Version81 || - d->pro == QPSQLDriver::Version82 || - d->pro == QPSQLDriver::Version83 || - d->pro == QPSQLDriver::Version84 || - d->pro == QPSQLDriver::Version9) { + if (d->pro >= QPSQLDriver::Version8) { transaction_failed = qstrcmp(PQcmdStatus(res), "ROLLBACK") == 0; } @@ -1085,8 +1122,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const else schema = std::move(schema).toLower(); - switch(d->pro) { - case QPSQLDriver::Version6: + if (d->pro == QPSQLDriver::Version6) { stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname " "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind " "where pg_cl.relname = '%1_pkey' " @@ -1095,9 +1131,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const "and pg_att1.attrelid = pg_ind.indrelid " "and pg_att1.attnum = pg_ind.indkey[pg_att2.attnum-1] " "order by pg_att2.attnum"); - break; - case QPSQLDriver::Version7: - case QPSQLDriver::Version71: + } else if (d->pro == QPSQLDriver::Version7 || d->pro == QPSQLDriver::Version7_1) { stmt = QLatin1String("select pg_att1.attname, pg_att1.atttypid::int, pg_cl.relname " "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind " "where pg_cl.relname = '%1_pkey' " @@ -1106,15 +1140,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const "and pg_att1.attrelid = pg_ind.indrelid " "and pg_att1.attnum = pg_ind.indkey[pg_att2.attnum-1] " "order by pg_att2.attnum"); - break; - case QPSQLDriver::Version73: - case QPSQLDriver::Version74: - case QPSQLDriver::Version8: - case QPSQLDriver::Version81: - case QPSQLDriver::Version82: - case QPSQLDriver::Version83: - case QPSQLDriver::Version84: - case QPSQLDriver::Version9: + } else if (d->pro >= QPSQLDriver::Version7_3) { stmt = QLatin1String("SELECT pg_attribute.attname, pg_attribute.atttypid::int, " "pg_class.relname " "FROM pg_attribute, pg_class " @@ -1129,10 +1155,8 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema)); - break; - case QPSQLDriver::VersionUnknown: - qFatal("PSQL version is unknown"); - break; + } else { + qFatal("QPSQLDriver::primaryIndex(tablename): unknown PSQL version, query statement not set"); } i.exec(stmt.arg(tbl)); @@ -1166,8 +1190,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const schema = std::move(schema).toLower(); QString stmt; - switch(d->pro) { - case QPSQLDriver::Version6: + if (d->pro == QPSQLDriver::Version6) { stmt = QLatin1String("select pg_attribute.attname, int(pg_attribute.atttypid), " "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "int(pg_attribute.attrelid), pg_attribute.attnum " @@ -1175,8 +1198,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "where pg_class.relname = '%1' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid "); - break; - case QPSQLDriver::Version7: + } else if (d->pro == QPSQLDriver::Version7) { stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, " "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "pg_attribute.attrelid::int, pg_attribute.attnum " @@ -1184,8 +1206,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "where pg_class.relname = '%1' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid "); - break; - case QPSQLDriver::Version71: + } else if (d->pro == QPSQLDriver::Version7_1) { stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, " "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "pg_attrdef.adsrc " @@ -1196,15 +1217,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid " "order by pg_attribute.attnum "); - break; - case QPSQLDriver::Version73: - case QPSQLDriver::Version74: - case QPSQLDriver::Version8: - case QPSQLDriver::Version81: - case QPSQLDriver::Version82: - case QPSQLDriver::Version83: - case QPSQLDriver::Version84: - case QPSQLDriver::Version9: + } else if (d->pro >= QPSQLDriver::Version7_3) { stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, " "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "pg_attrdef.adsrc " @@ -1222,15 +1235,13 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " "pg_namespace where pg_namespace.nspname = '%1')").arg(schema)); - break; - case QPSQLDriver::VersionUnknown: - qFatal("PSQL version is unknown"); - break; + } else { + qFatal("QPSQLDriver::record(tablename): unknown PSQL version, query statement not set"); } QSqlQuery query(createResult()); query.exec(stmt.arg(tbl)); - if (d->pro >= QPSQLDriver::Version71) { + if (d->pro >= QPSQLDriver::Version7_1) { while (query.next()) { int len = query.value(3).toInt(); int precision = query.value(4).toInt(); diff --git a/src/plugins/sqldrivers/psql/qsql_psql_p.h b/src/plugins/sqldrivers/psql/qsql_psql_p.h index 8468b9af93..f5cb2e9bd0 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql_p.h +++ b/src/plugins/sqldrivers/psql/qsql_psql_p.h @@ -76,15 +76,23 @@ public: VersionUnknown = -1, Version6 = 6, Version7 = 7, - Version71 = 8, - Version73 = 9, - Version74 = 10, + Version7_1 = 8, + Version7_3 = 9, + Version7_4 = 10, Version8 = 11, - Version81 = 12, - Version82 = 13, - Version83 = 14, - Version84 = 15, - Version9 = 16 + Version8_1 = 12, + Version8_2 = 13, + Version8_3 = 14, + Version8_4 = 15, + Version9 = 16, + Version9_1 = 17, + Version9_2 = 18, + Version9_3 = 19, + Version9_4 = 20, + Version9_5 = 21, + Version9_6 = 22, + Version10 = 23, + UnknownLaterVersion = 100000 }; explicit QPSQLDriver(QObject *parent=0); |