diff options
author | Tony Sarajärvi <tony.sarajarvi@qt.io> | 2018-02-20 04:18:00 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2018-02-20 04:18:00 +0000 |
commit | 3190edb07735bb47b7cf85c582d415ab6487a446 (patch) | |
tree | 3e3dd3d0c3902ef82d93b99e235a8bc5d1b66309 | |
parent | 13e51ea48758337397164a548d4c82d079067ae3 (diff) | |
parent | 48577b2e7f17a26c1d903cb8ecbd30e41c231137 (diff) |
Merge "Merge remote-tracking branch 'origin/5.10.1' into 5.11" into refs/staging/5.11
-rw-r--r-- | dist/changes-5.10.1 | 154 | ||||
-rw-r--r-- | src/corelib/tools/qstring.cpp | 9 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 2 | ||||
-rw-r--r-- | src/plugins/sqldrivers/psql/qsql_psql.cpp | 11 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qstring/tst_qstring.cpp | 8 | ||||
-rw-r--r-- | tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp | 46 | ||||
-rw-r--r-- | tests/benchmarks/sql/kernel/kernel.pro | 1 | ||||
-rw-r--r-- | tests/benchmarks/sql/kernel/qsqlrecord/qsqlrecord.pro | 5 | ||||
-rw-r--r-- | tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp | 191 |
9 files changed, 411 insertions, 16 deletions
diff --git a/dist/changes-5.10.1 b/dist/changes-5.10.1 new file mode 100644 index 0000000000..1c9854fa64 --- /dev/null +++ b/dist/changes-5.10.1 @@ -0,0 +1,154 @@ +Qt 5.10.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.10.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.10 series is binary compatible with the 5.9.x series. +Applications compiled for 5.9 will continue to run with 5.10. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +This release contains all fixes included in the Qt 5.9.4 release. + +**************************************************************************** +* Library * +**************************************************************************** + +QtCore +------ + + - [QTBUG-64529] Fixed a compilation issue with qfloat16 if AVX2 support is + enabled in the compiler. Since all processors that support AVX2 also + support F16C, for GCC and Clang it is recommended to either add -mf16c + to your build or to use the corresponding -march= switch. + + - QCoreApplication: + * [QTBUG-58919] Fixed a crash if QCoreApplication is recreated on Windows + and the passed argv parameter is different. + + - QFile: + * [QTBUG-64103] Fixed a regression in doing rename() on Android + Marshmallow. + + - QFileInfo: + * [QTBUG-30148] Fixed isWritable() on Windows to return whether the given + file is writable only under current privilege levels. Previously, the + result would take into account privilege elevation. + + - QMetaObject: + * [QTBUG-65462] Fixed a memory leak that happened when the new-style + call to invokeMethod() was used. + + - QObject: + * [QTBUG-65712] Improved performance of QObject::deleteLater. + * Fixed a crash that could happen if the context QObject pointer passed to + new-style connect() was null. + + - QPluginLoader: + * [QTBUG-65197] Fixed a bug that would cause the Qt plugin scanning + system to allocate too much memory and possibly crash the process. + + - QProcess: + * [QTBUG-65076] Fixed a regression that made QProcess be unable to find + executables when the PATH environment variable on some Unix systems + wasn't set. This behavior should not be relied upon since many systems + do not have sensible fallback values for PATH. + + - QRandomGenerator: + * [QTBUG-65414] Fixed compilation on Windows if the windows.h header was + included before this qrandom.h. + + - QSettings: + * [QTBUG-64121] Fixed reading from NTFS symbolic links. + + - QStandardPaths: + * [QTBUG-65076] findExecutable() will now apply the default value for + the PATH environment variable (as returned by the POSIX confstr(3) + function or found in <paths.h>) if the variable isn't set in the + environment. + * [QTBUG-65687] Fixed a memory leak with displayName() on Apple platforms. + * On Windows, it is now possible to resolve configuration paths even + without QCoreApplication created. + + - QString: + * [QTBUG-65939] Fixed a regression from 5.9 that caused comparing + default-constructed QStrings to be sorted after non-empty strings. + + - QTextBoundaryFinder: + * [QTBUG-63191] Fixed a bug in the generating of Unicode data, affecting + the joining properties of characters like U+200C ZWNJ. + + - QXmlStreamWriter: + * [QTBUG-63538] Empty namespace URIs are now possible. + + - State Machine: + * [QTBUG-61463] Fixed a failed assertion that could happen when emitting a + signal from another thread. + +QtGui +----- + + - Text: + * [QTBUG-61882] Fixed a bug where mixing different writing systems with + emojis could lead to missing glyphs. + * [QTBUG-65519] Fixed ZWJ and ZWNJ control characters when fallback + fonts are in use. + +**************************************************************************** +* Platform-specific Changes * +**************************************************************************** + + - QNX: + * [QTBUG-64033] Fixed the detection of slog2 with QNX 7.0 + + - Windows: + * Named pipes internally created by QProcess now contain the PID in their + name to ensure uniqueness. + * [QTBUG-65940] Fixed asserts and crashes in QWinEventNotifier. + + - WinRT: + * -qdevel and -qdebug are removed from the command line arguments and + not passed to the application. + +**************************************************************************** +* Third-Party Code * +**************************************************************************** + + - libjpeg-turbo was updated to version 1.5.3 + +**************************************************************************** +* Tools * +**************************************************************************** + +configure & build system +------------------------ + + - [QTBUG-65753] Fixed installation of resource sources in some examples. + - Qt's pkg-config .pc files now add -DQT_{module}_LIB to CFLAGS. + +qmake +----- + + - [QTBUG-65106] The value of QT is now silently ignored when the sub- + project already failed requires()/REQUIRES. + - [QTBUG-63442] Fixed an issue that would cause warnings with CMake 3.10 + for projects that used AUTOMOC. + - [QTBUG-63637][MinGW] Fixed cross compilation from Linux. + - [QTBUG-65103] Introduced precompile_header_c CONFIG option for MSVC to + enable precompiled header for C sources. + - [QTBUG-65477][Darwin] Added escaping to @BUNDLEIDENTIFIER@. + - [Darwin] Rewrote handling of placeholders in Info.plist; the preferred + style is now ${} and is consistent between Xcode and Makefile generators. + - [Windows] Fixed path separators when setting working directory in + "make check". + - [Windows] Paths which are relative to the current drive's root are not + treated as absolute any more. diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 08fe9b899d..b56ad34546 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -568,10 +568,6 @@ static int ucstricmp(const QChar *a, const QChar *ae, const QChar *b, const QCha { if (a == b) return (ae - be); - if (a == 0) - return be - b; - if (b == 0) - return a - ae; const QChar *e = ae; if (be - b < ae - a) @@ -600,11 +596,6 @@ static int ucstricmp(const QChar *a, const QChar *ae, const QChar *b, const QCha // Case-insensitive comparison between a Unicode string and a QLatin1String static int ucstricmp(const QChar *a, const QChar *ae, const char *b, const char *be) { - if (!a) - return be - b; - if (!b) - return a - ae; - auto e = ae; if (be - b < ae - a) e = a + (be - b); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 511c471519..17ded6ce59 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1131,7 +1131,7 @@ void QCocoaWindow::handleGeometryChange() // Guard against processing window system events during QWindow::setGeometry // calls, which Qt and Qt applications do not expect. if (!m_inSetGeometry) - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); } void QCocoaWindow::handleExposeEvent(const QRegion ®ion) diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index 6f105f79ca..368b777ca5 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -204,6 +204,7 @@ public: void setDatestyle(); void setByteaOutput(); void detectBackslashEscape(); + mutable QHash<int, QString> oidToTable; }; void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type) @@ -815,18 +816,20 @@ QSqlRecord QPSQLResult::record() const f.setName(QString::fromUtf8(PQfname(d->result, i))); else f.setName(QString::fromLocal8Bit(PQfname(d->result, i))); - + const int tableOid = PQftable(d->result, i); + auto &tableName = d->drv_d_func()->oidToTable[tableOid]; // WARNING: We cannot execute any other SQL queries on // the same db connection while forward-only mode is active // (this would discard all results of forward-only query). // So we just skip this... - if (!isForwardOnly()) { + if (tableName.isEmpty() && !isForwardOnly()) { QSqlQuery qry(driver()->createResult()); if (qry.exec(QStringLiteral("SELECT relname FROM pg_class WHERE pg_class.oid = %1") - .arg(PQftable(d->result, i))) && qry.next()) { - f.setTableName(qry.value(0).toString()); + .arg(tableOid)) && qry.next()) { + tableName = qry.value(0).toString(); } } + f.setTableName(tableName); int ptype = PQftype(d->result, i); f.setType(qDecodePSQLType(ptype)); int len = PQfsize(d->result, i); diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 90cd70f43e..86cc2cd02f 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -6049,8 +6049,14 @@ void tst_QString::compare_data() QTest::addColumn<int>("csr"); // case sensitive result QTest::addColumn<int>("cir"); // case insensitive result - // null strings + QTest::newRow("null-null") << QString() << QString() << 0 << 0; + QTest::newRow("text-null") << QString("a") << QString() << 1 << 1; + QTest::newRow("null-text") << QString() << QString("a") << -1 << -1; + QTest::newRow("null-empty") << QString() << QString("") << 0 << 0; + QTest::newRow("empty-null") << QString("") << QString() << 0 << 0; + + // empty strings QTest::newRow("data0") << QString("") << QString("") << 0 << 0; QTest::newRow("data1") << QString("a") << QString("") << 1 << 1; QTest::newRow("data2") << QString("") << QString("a") << -1 << -1; diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index baf2551dfb..ada57996f4 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -370,7 +370,8 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) << qTableName("task_234422", __FILE__, db) << qTableName("test141895", __FILE__, db) << qTableName("qtest_oraOCINumber", __FILE__, db) - << qTableName("bug2192", __FILE__, db); + << qTableName("bug2192", __FILE__, db) + << qTableName("tst_record", __FILE__, db); if (dbType == QSqlDriver::PostgreSQL) tablenames << qTableName("task_233829", __FILE__, db); @@ -1009,6 +1010,29 @@ void tst_QSqlQuery::value() } } +#define SETUP_RECORD_TABLE \ + do { \ + QVERIFY_SQL(q, exec("CREATE TABLE " + tst_record + " (id integer, extra varchar(50))")); \ + for (int i = 0; i < 3; ++i) \ + QVERIFY_SQL(q, exec(QString("INSERT INTO " + tst_record + " VALUES(%1, 'extra%1')").arg(i))); \ + } while (0) + +#define CHECK_RECORD \ + do { \ + QVERIFY_SQL(q, exec(QString("select %1.id, %1.t_varchar, %1.t_char, %2.id, %2.extra from %1, %2 where " \ + "%1.id = %2.id order by %1.id").arg(lowerQTest).arg(tst_record))); \ + QCOMPARE(q.record().fieldName(0).toLower(), QString("id")); \ + QCOMPARE(q.record().field(0).tableName().toLower(), lowerQTest); \ + QCOMPARE(q.record().fieldName(1).toLower(), QString("t_varchar")); \ + QCOMPARE(q.record().field(1).tableName().toLower(), lowerQTest); \ + QCOMPARE(q.record().fieldName(2).toLower(), QString("t_char")); \ + QCOMPARE(q.record().field(2).tableName().toLower(), lowerQTest); \ + QCOMPARE(q.record().fieldName(3).toLower(), QString("id")); \ + QCOMPARE(q.record().field(3).tableName().toLower(), tst_record); \ + QCOMPARE(q.record().fieldName(4).toLower(), QString("extra")); \ + QCOMPARE(q.record().field(4).tableName().toLower(), tst_record); \ + } while (0) + void tst_QSqlQuery::record() { QFETCH( QString, dbName ); @@ -1030,6 +1054,26 @@ void tst_QSqlQuery::record() QCOMPARE( q.record().fieldName( 0 ).toLower(), QString( "id" ) ); QCOMPARE( q.value( 0 ).toInt(), 2 ); + + const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriver::Oracle) + QSKIP("Getting the tablename is not supported in Oracle"); + const auto lowerQTest = qtest.toLower(); + for (int i = 0; i < 3; ++i) + QCOMPARE(q.record().field(i).tableName().toLower(), lowerQTest); + q.clear(); + const auto tst_record = qTableName("tst_record", __FILE__, db).toLower(); + SETUP_RECORD_TABLE; + CHECK_RECORD; + q.clear(); + + // Recreate the tables, in a different order + const QStringList tables = { qtest, tst_record, qTableName("qtest_null", __FILE__, db) }; + tst_Databases::safeDropTables(db, tables); + SETUP_RECORD_TABLE; + createTestTables(db); + populateTestTables(db); + CHECK_RECORD; } void tst_QSqlQuery::isValid() diff --git a/tests/benchmarks/sql/kernel/kernel.pro b/tests/benchmarks/sql/kernel/kernel.pro index f907feeeac..63887daf5f 100644 --- a/tests/benchmarks/sql/kernel/kernel.pro +++ b/tests/benchmarks/sql/kernel/kernel.pro @@ -1,3 +1,4 @@ TEMPLATE = subdirs SUBDIRS = \ qsqlquery \ + qsqlrecord diff --git a/tests/benchmarks/sql/kernel/qsqlrecord/qsqlrecord.pro b/tests/benchmarks/sql/kernel/qsqlrecord/qsqlrecord.pro new file mode 100644 index 0000000000..840a11bfbe --- /dev/null +++ b/tests/benchmarks/sql/kernel/qsqlrecord/qsqlrecord.pro @@ -0,0 +1,5 @@ +TARGET = tst_bench_qsqlrecord + +SOURCES += tst_qsqlrecord.cpp + +QT = core sql testlib core-private sql-private diff --git a/tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp b/tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp new file mode 100644 index 0000000000..465dabca0e --- /dev/null +++ b/tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** + ** + ** Copyright (C) 2018 The Qt Company Ltd. + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the test suite of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ + ** Commercial License Usage + ** Licensees holding valid commercial Qt licenses may use this file in + ** accordance with the commercial license agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and The Qt Company. For licensing terms + ** and conditions see https://www.qt.io/terms-conditions. For further + ** information use the contact form at https://www.qt.io/contact-us. + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License version 3 as published by the Free Software + ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT + ** included in the packaging of this file. Please review the following + ** information to ensure the GNU General Public License requirements will + ** be met: https://www.gnu.org/licenses/gpl-3.0.html. + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtSql/QtSql> + +#include "../../../../auto/sql/kernel/qsqldatabase/tst_databases.h" + +const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase())); + +class tst_QSqlRecord : public QObject +{ + Q_OBJECT + +public: + tst_QSqlRecord(); + virtual ~tst_QSqlRecord(); + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void benchmarkRecord_data() { generic_data(); } + void benchmarkRecord(); + +private: + void generic_data(const QString &engine = QString()); + void dropTestTables(QSqlDatabase db); + void createTestTables(QSqlDatabase db); + void populateTestTables(QSqlDatabase db); + + tst_Databases dbs; +}; + +QTEST_MAIN(tst_QSqlRecord) + +tst_QSqlRecord::tst_QSqlRecord() +{ +} + +tst_QSqlRecord::~tst_QSqlRecord() +{ +} + +void tst_QSqlRecord::initTestCase() +{ + dbs.open(); + for (const auto &dbName : qAsConst(dbs.dbNames)) { + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + dropTestTables(db); // In case of leftovers + createTestTables(db); + populateTestTables(db); + } +} + +void tst_QSqlRecord::cleanupTestCase() +{ + for (const auto &dbName : qAsConst(dbs.dbNames)) { + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + dropTestTables(db); + } + dbs.close(); +} + +void tst_QSqlRecord::init() +{ +} + +void tst_QSqlRecord::cleanup() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); + + if (QTest::currentTestFailed() && (dbType == QSqlDriver::Oracle || + db.driverName().startsWith("QODBC"))) { + // Since Oracle ODBC has a problem when encountering an error, we init again + db.close(); + db.open(); + } +} + +void tst_QSqlRecord::generic_data(const QString &engine) +{ + if (dbs.fillTestTable(engine) == 0) { + if (engine.isEmpty()) + QSKIP("No database drivers are available in this Qt configuration"); + else + QSKIP(QString("No database drivers of type %1 are available in this Qt configuration").arg(engine).toLocal8Bit()); + } +} + +void tst_QSqlRecord::dropTestTables(QSqlDatabase db) +{ + QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); + QStringList tablenames; + // drop all the tables in case a testcase failed + tablenames << qtest + << qTableName("record", __FILE__, db); + tst_Databases::safeDropTables(db, tablenames); + + if (dbType == QSqlDriver::Oracle) { + QSqlQuery q(db); + q.exec("DROP PACKAGE " + qTableName("pkg", __FILE__, db)); + } +} + +void tst_QSqlRecord::createTestTables(QSqlDatabase db) +{ + QSqlQuery q(db); + switch (tst_Databases::getDatabaseType(db)) { + case QSqlDriver::PostgreSQL: + QVERIFY_SQL(q, exec("set client_min_messages='warning'")); + QVERIFY_SQL(q, exec("create table " + qtest + " (id serial NOT NULL, t_varchar varchar(20), " + "t_char char(20), primary key(id)) WITH OIDS")); + break; + case QSqlDriver::MySqlServer: + QVERIFY_SQL(q, exec("set table_type=innodb")); + Q_FALLTHROUGH(); + default: + QVERIFY_SQL(q, exec("create table " + qtest + " (id int " + tst_Databases::autoFieldName(db) + + " NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))")); + break; + } +} + +void tst_QSqlRecord::populateTestTables(QSqlDatabase db) +{ + QSqlQuery q(db); + QVERIFY_SQL(q, exec("delete from " + qtest)); + QVERIFY_SQL(q, exec("insert into " + qtest + " values (1, 'VarChar1', 'Char1')")); + QVERIFY_SQL(q, exec("insert into " + qtest + " values (2, 'VarChar2', 'Char2')")); + QVERIFY_SQL(q, exec("insert into " + qtest + " values (3, 'VarChar3', 'Char3')")); + QVERIFY_SQL(q, exec("insert into " + qtest + " values (4, 'VarChar4', 'Char4')")); + QVERIFY_SQL(q, exec("insert into " + qtest + " values (5, 'VarChar5', 'Char5')")); +} + +void tst_QSqlRecord::benchmarkRecord() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + const auto tableName = qTableName("record", __FILE__, db); + { + QSqlQuery qry(db); + QVERIFY_SQL(qry, exec("create table " + tableName + " (id int NOT NULL, t_varchar varchar(20), " + "t_char char(20), primary key(id))")); + for (int i = 0; i < 1000; i++) + QVERIFY_SQL(qry, exec(QString("INSERT INTO " + tableName + + " VALUES (%1, 'VarChar%1', 'Char%1')").arg(i))); + QVERIFY_SQL(qry, exec(QString("SELECT * from ") + tableName)); + QBENCHMARK { + while (qry.next()) + qry.record(); + } + } + tst_Databases::safeDropTables(db, QStringList() << tableName); +} + +#include "tst_qsqlrecord.moc" |