Always escape the table names when creating the SQL statement

Since some databases are case sensitive if part of the query is quoted,
then we should ensure that all instances of the table name are escaped
unless the test is delibrately testing the non-escaped case.

As a result, this commit also removes some expected failures pertaining
to PostgreSQL and also adds an entry to the list of tables being dropped
when a test is finished.

[ChangeLog][Sql][PostgreSQL] QSqlDatabase is now stricter about table
names when used with record() and primaryIndex(). If the tablename was
not quoted when it was created, then the table name passed to record()
and primaryIndex() needs to be in lower case so that PostgreSQL is
able to find it.

Fixes: QTBUG-65788
Change-Id: Id1f54cb66b761c39edf858501b730ede7eec1fd3
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
bb10
Andy Shaw 2018-01-16 09:54:01 +01:00 committed by Christian Ehrlicher
parent 7c69f6171d
commit 461ef575bc
11 changed files with 138 additions and 106 deletions

View File

@ -1551,7 +1551,7 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const
QSqlQuery i(createResult());
QString stmt(QLatin1String("show index from %1;"));
QSqlRecord fil = record(tablename);
i.exec(stmt.arg(tablename));
i.exec(stmt.arg(escapeIdentifier(tablename, QSqlDriver::TableName)));
while (i.isActive() && i.next()) {
if (i.value(2).toString() == QLatin1String("PRIMARY")) {
idx.append(fil.field(i.value(4).toString()));

View File

@ -1393,16 +1393,8 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
QString tbl = tablename;
QString schema;
qSplitTableName(tbl, schema);
if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
tbl = stripDelimiters(tbl, QSqlDriver::TableName);
else
tbl = std::move(tbl).toLower();
if (isIdentifierEscaped(schema, QSqlDriver::TableName))
schema = stripDelimiters(schema, QSqlDriver::TableName);
else
schema = std::move(schema).toLower();
schema = stripDelimiters(schema, QSqlDriver::TableName);
tbl = stripDelimiters(tbl, QSqlDriver::TableName);
QString stmt = QStringLiteral("SELECT pg_attribute.attname, pg_attribute.atttypid::int, "
"pg_class.relname "
@ -1437,16 +1429,8 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
QString tbl = tablename;
QString schema;
qSplitTableName(tbl, schema);
if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
tbl = stripDelimiters(tbl, QSqlDriver::TableName);
else
tbl = std::move(tbl).toLower();
if (isIdentifierEscaped(schema, QSqlDriver::TableName))
schema = stripDelimiters(schema, QSqlDriver::TableName);
else
schema = std::move(schema).toLower();
schema = stripDelimiters(schema, QSqlDriver::TableName);
tbl = stripDelimiters(tbl, QSqlDriver::TableName);
QString stmt = QStringLiteral("SELECT pg_attribute.attname, pg_attribute.atttypid::int, "
"pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, "

View File

@ -237,3 +237,16 @@ Could not create database object
//! [38]
QPSQLDriver::getResult: Query results lost - probably discarded on executing another SQL query.
//! [38]
//! [39]
CREATE TABLE "testTable" ("id" INTEGER);
//! [39]
//! [40]
QString tableString("testTable");
QSqlQuery q;
// Create table query is not quoted, therefore it is mapped to lower case
q.exec(QString("CREATE TABLE %1 (id INTEGER)").arg(tableString));
// Call toLower() on the string so that it can be matched
QSqlRecord rec = database.record(tableString.toLower());
//! [40]

View File

@ -381,6 +381,23 @@
multibyte enabled PostgreSQL server can be found in the PostgreSQL
Administrator Guide, Chapter 5.
\section3 QPSQL Case Sensitivity
PostgreSQL databases will only respect case sensitivity if the table or field
name is quoted when the table is created. So for example, a SQL query such
as:
\snippet code/doc_src_sql-driver.qdoc 39
will ensure that it can be accessed with the same case that was used. If the
table or field name is not quoted when created, the actual table name
or field name will be lower-case. When QSqlDatabase::record() or
QSqlDatabase::primaryIndex() access a table or field that was unquoted
when created, the name passed to the function must be lower-case to
ensure it is found. For example:
\snippet code/doc_src_sql-driver.qdoc 40
\section3 QPSQL BLOB Support
Binary Large Objects are supported through the \c BYTEA field type in

View File

@ -1088,6 +1088,11 @@ QStringList QSqlDatabase::tables(QSql::TableType type) const
Returns the primary index for table \a tablename. If no primary
index exists, an empty QSqlIndex is returned.
\note Some drivers, such as the \l {QPSQL Case Sensitivity}{QPSQL}
driver, may may require you to pass \a tablename in lower case if
the table was not quoted when created. See the
\l{sql-driver.html}{Qt SQL driver} documentation for more information.
\sa tables(), record()
*/
@ -1102,6 +1107,11 @@ QSqlIndex QSqlDatabase::primaryIndex(const QString& tablename) const
the table (or view) called \a tablename. The order in which the
fields appear in the record is undefined. If no such table (or
view) exists, an empty record is returned.
\note Some drivers, such as the \l {QPSQL Case Sensitivity}{QPSQL}
driver, may may require you to pass \a tablename in lower case if
the table was not quoted when created. See the
\l{sql-driver.html}{Qt SQL driver} documentation for more information.
*/
QSqlRecord QSqlDatabase::record(const QString& tablename) const

View File

@ -488,6 +488,8 @@ QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType ty
QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
const QSqlRecord &rec, bool preparedStatement) const
{
const auto tableNameString = tableName.isEmpty() ? QString()
: prepareIdentifier(tableName, QSqlDriver::TableName, this);
int i;
QString s;
s.reserve(128);
@ -500,13 +502,12 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
if (s.isEmpty())
return s;
s.chop(2);
s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName);
s = QLatin1String("SELECT ") + s + QLatin1String(" FROM ") + tableNameString;
break;
case WhereStatement:
{
const QString tableNamePrefix = tableName.isEmpty()
? QString()
: prepareIdentifier(tableName, QSqlDriver::TableName, this) + QLatin1Char('.');
const QString tableNamePrefix = tableNameString.isEmpty()
? QString() : tableNameString + QLatin1Char('.');
for (int i = 0; i < rec.count(); ++i) {
if (!rec.isGenerated(i))
continue;
@ -523,8 +524,7 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
break;
}
case UpdateStatement:
s.append(QLatin1String("UPDATE ")).append(tableName).append(
QLatin1String(" SET "));
s = s + QLatin1String("UPDATE ") + tableNameString + QLatin1String(" SET ");
for (i = 0; i < rec.count(); ++i) {
if (!rec.isGenerated(i))
continue;
@ -541,10 +541,10 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
s.clear();
break;
case DeleteStatement:
s.append(QLatin1String("DELETE FROM ")).append(tableName);
s = s + QLatin1String("DELETE FROM ") + tableNameString;
break;
case InsertStatement: {
s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" ("));
s = s + QLatin1String("INSERT INTO ") + tableNameString + QLatin1String(" (");
QString vals;
for (i = 0; i < rec.count(); ++i) {
if (!rec.isGenerated(i))

View File

@ -79,14 +79,14 @@ inline QString fixupTableName(const QString &tableName, QSqlDatabase db)
return tbName;
}
inline static QString qTableName(const QString& prefix, const char *sourceFileName, QSqlDatabase db)
inline static QString qTableName(const QString &prefix, const char *sourceFileName,
QSqlDatabase db, bool escape = true)
{
QString tableStr = QLatin1String("dbtst");
if (db.driverName().toLower().contains("ODBC"))
tableStr += QLatin1String("_odbc");
return fixupTableName(QString(QLatin1String("dbtst") + db.driverName() +
QString::number(qHash(QLatin1String(sourceFileName) +
"_" + qGetHostName().replace( "-", "_" )), 16) + "_" + prefix), db);
const auto tableStr = fixupTableName(QString(QLatin1String("dbtst") + db.driverName() +
QString::number(qHash(QLatin1String(sourceFileName) +
"_" + qGetHostName().replace("-", "_")), 16) +
"_" + prefix), db);
return escape ? db.driver()->escapeIdentifier(tableStr, QSqlDriver::TableName) : tableStr;
}
inline static QString qTableName(const QString& prefix, QSqlDatabase db)

View File

@ -314,10 +314,8 @@ void tst_QSqlDatabase::createTestTables(QSqlDatabase db)
" (id integer not null, t_varchar varchar(40) not null, "
"t_char char(40), t_numeric numeric(6, 3), primary key (id, t_varchar))"));
}
if (testWhiteSpaceNames(db.driverName())) {
QString qry = "create table "
+ db.driver()->escapeIdentifier(tableName + " test", QSqlDriver::TableName)
QString qry = "create table " + qTableName("qtest test", __FILE__, db)
+ '('
+ db.driver()->escapeIdentifier(QLatin1String("test test"), QSqlDriver::FieldName)
+ " int not null primary key)";
@ -341,6 +339,7 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db)
const QString qtestTable = qTableName("qtest", __FILE__, db);
QStringList tableNames;
tableNames << qtestTable
<< qTableName("qtest test", __FILE__, db)
<< qTableName("qtestfields", __FILE__, db)
<< qTableName("qtestalter", __FILE__, db)
<< qTableName("qtest_temp", __FILE__, db)
@ -513,7 +512,9 @@ void tst_QSqlDatabase::tables()
CHECK_DATABASE(db);
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
const QString qtest(qTableName("qtest", __FILE__, db)), qtest_view(qTableName("qtest_view", __FILE__, db)), temp_tab(qTableName("test_tab", __FILE__, db));
const auto qtest(qTableName("qtest", __FILE__, db, false)),
qtest_view(qTableName("qtest_view", __FILE__, db, false)),
temp_tab(qTableName("test_tab", __FILE__, db, false));
bool views = true;
bool tempTables = false;
@ -578,10 +579,10 @@ void tst_QSqlDatabase::whitespaceInIdentifiers()
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (testWhiteSpaceNames(db.driverName())) {
const QString tableName(qTableName("qtest", __FILE__, db) + " test");
const auto tableName(qTableName("qtest test", __FILE__, db, false));
QVERIFY(db.tables().contains(tableName, Qt::CaseInsensitive));
QSqlRecord rec = db.record(db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName));
QSqlRecord rec = db.record(tableName);
QCOMPARE(rec.count(), 1);
QCOMPARE(rec.fieldName(0), QString("test test"));
if (dbType == QSqlDriver::Oracle)
@ -589,7 +590,7 @@ void tst_QSqlDatabase::whitespaceInIdentifiers()
else
QCOMPARE(rec.field(0).type(), QVariant::Int);
QSqlIndex idx = db.primaryIndex(db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName));
QSqlIndex idx = db.primaryIndex(tableName);
QCOMPARE(idx.count(), 1);
QCOMPARE(idx.fieldName(0), QString("test test"));
if (dbType == QSqlDriver::Oracle)
@ -607,11 +608,12 @@ void tst_QSqlDatabase::alterTable()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
const QString qtestalter(qTableName("qtestalter", __FILE__, db));
const auto noEscapeAlterTable = qTableName("qtestalter", __FILE__, db, false);
QSqlQuery q(db);
QVERIFY_SQL(q, exec("create table " + qtestalter + " (F1 char(20), F2 char(20), F3 char(20))"));
QSqlRecord rec = db.record(qtestalter);
QSqlRecord rec = db.record(noEscapeAlterTable);
QCOMPARE((int)rec.count(), 3);
int i;
@ -623,7 +625,7 @@ void tst_QSqlDatabase::alterTable()
QSKIP("DBMS doesn't support dropping columns in ALTER TABLE statement");
}
rec = db.record(qtestalter);
rec = db.record(noEscapeAlterTable);
QCOMPARE((int)rec.count(), 2);
@ -681,13 +683,16 @@ void tst_QSqlDatabase::testRecord(const FieldDef fieldDefs[], const QSqlRecord&
void tst_QSqlDatabase::commonFieldTest(const FieldDef fieldDefs[], QSqlDatabase db, const int fieldCount)
{
CHECK_DATABASE(db);
const QString tableName = qTableName("qtestfields", __FILE__, db);
QSqlRecord rec = db.record(tableName);
QCOMPARE((int)rec.count(), fieldCount+1);
testRecord(fieldDefs, rec, db);
const QStringList tableNames = { qTableName("qtestfields", __FILE__, db),
qTableName("qtestfields", __FILE__, db, false) };
for (const QString table : tableNames) {
QSqlRecord rec = db.record(table);
QCOMPARE(rec.count(), fieldCount + 1);
testRecord(fieldDefs, rec, db);
}
QSqlQuery q(db);
QVERIFY_SQL(q, exec("select * from " + tableName));
// Only check the escaped entry
QVERIFY_SQL(q, exec("select * from " + tableNames.at(0)));
}
void tst_QSqlDatabase::recordTDS()
@ -846,12 +851,8 @@ void tst_QSqlDatabase::recordPSQL()
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::PostgreSQL)
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
const QString tableName = qTableName("qtestfields", __FILE__, db);
q.exec("drop sequence " + tableName + "_t_bigserial_seq");
q.exec("drop sequence " + tableName + "_t_serial_seq");
// older psql cut off the table name
q.exec("drop sequence " + tableName + "_t_bigserial_seq");
q.exec("drop sequence " + tableName + "_t_serial_seq");
q.exec("drop sequence " + qTableName("qtestfields_t_bigserial_seq", __FILE__, db));
q.exec("drop sequence " + qTableName("qtestfields_t_serial_seq", __FILE__, db));
const int fieldCount = createFieldTable(fieldDefs, db);
QVERIFY(fieldCount > 0);
@ -1205,27 +1206,40 @@ void tst_QSqlDatabase::caseSensivity()
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
bool cs = false;
if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::SQLite || dbType == QSqlDriver::Sybase
if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::SQLite
|| dbType == QSqlDriver::Sybase || dbType == QSqlDriver::PostgreSQL
|| dbType == QSqlDriver::MSSqlServer || db.driverName().startsWith("QODBC"))
cs = true;
QSqlRecord rec = db.record(qTableName("qtest", __FILE__, db));
QSqlRecord rec = db.record(qTableName("qtest", __FILE__, db, false));
QVERIFY((int)rec.count() > 0);
if (!cs) {
rec = db.record(qTableName("QTEST", __FILE__, db).toUpper());
rec = db.record(qTableName("QTEST", __FILE__, db, false).toUpper());
QVERIFY((int)rec.count() > 0);
rec = db.record(qTableName("qTesT", __FILE__, db));
rec = db.record(qTableName("qTesT", __FILE__, db, false));
QVERIFY((int)rec.count() > 0);
}
rec = db.primaryIndex(qTableName("qtest", __FILE__, db));
rec = db.primaryIndex(qTableName("qtest", __FILE__, db, false));
QVERIFY((int)rec.count() > 0);
if (!cs) {
rec = db.primaryIndex(qTableName("QTEST", __FILE__, db).toUpper());
rec = db.primaryIndex(qTableName("QTEST", __FILE__, db, false).toUpper());
QVERIFY((int)rec.count() > 0);
rec = db.primaryIndex(qTableName("qTesT", __FILE__, db));
rec = db.primaryIndex(qTableName("qTesT", __FILE__, db, false));
QVERIFY((int)rec.count() > 0);
}
// Explicit test for case sensitive table creation without quoting
QSqlQuery qry(db);
const auto noQuotesTable = qTableName("NoQuotes", __FILE__, db, false);
tst_Databases::safeDropTable(db, noQuotesTable);
QVERIFY_SQL(qry, exec("CREATE TABLE " + noQuotesTable + " (id INTEGER)"));
QVERIFY_SQL(qry, exec("INSERT INTO " + noQuotesTable + " VALUES(1)"));
QVERIFY_SQL(qry, exec("SELECT * FROM " + noQuotesTable));
QVERIFY_SQL(qry, next());
QCOMPARE(qry.value(0).toInt(), 1);
rec = db.record(cs ? noQuotesTable.toLower() : noQuotesTable);
QVERIFY(rec.count() > 0);
}
void tst_QSqlDatabase::noEscapedFieldNamesInRecord()
@ -1260,17 +1274,19 @@ void tst_QSqlDatabase::psql_schemas()
const QString schemaName = qTableName("qtestschema", __FILE__, db);
QVERIFY_SQL(q, exec("CREATE SCHEMA " + schemaName));
QString table = schemaName + '.' + qTableName("qtesttable", __FILE__, db);
const auto table = schemaName + '.' + qTableName("qtesttable", __FILE__, db);
const auto noescapeTable = qTableName("qtestschema", __FILE__, db, false) + '.' +
qTableName("qtesttable", __FILE__, db, false);
QVERIFY_SQL(q, exec("CREATE TABLE " + table + " (id int primary key, name varchar(20))"));
QVERIFY(db.tables().contains(table, Qt::CaseInsensitive));
QVERIFY(db.tables().contains(noescapeTable, Qt::CaseInsensitive));
QSqlRecord rec = db.record(table);
QSqlRecord rec = db.record(noescapeTable);
QCOMPARE(rec.count(), 2);
QCOMPARE(rec.fieldName(0), QString("id"));
QCOMPARE(rec.fieldName(1), QString("name"));
QSqlIndex idx = db.primaryIndex(table);
QSqlIndex idx = db.primaryIndex(noescapeTable);
QCOMPARE(idx.count(), 1);
QCOMPARE(idx.fieldName(0), QString("id"));
}
@ -1288,18 +1304,21 @@ void tst_QSqlDatabase::psql_escapedIdentifiers()
QSqlQuery q(db);
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
const QString schemaName(qTableName("qtestScHeMa", __FILE__, db)),
const char bumpyCase[] = "qtestScHeMa";
const QString schemaName(qTableName(bumpyCase, __FILE__, db)),
tableName(qTableName("qtest", __FILE__, db)),
field1Name(QLatin1String("fIeLdNaMe")),
field2Name(QLatin1String("ZuLu"));
q.exec(QString("DROP SCHEMA \"%1\" CASCADE").arg(schemaName));
QString createSchema = QString("CREATE SCHEMA \"%1\"").arg(schemaName);
q.exec(QString("DROP SCHEMA %1 CASCADE").arg(schemaName));
const auto createSchema = QString("CREATE SCHEMA %1").arg(schemaName);
QVERIFY_SQL(q, exec(createSchema));
QString createTable = QString("CREATE TABLE \"%1\".\"%2\" (\"%3\" int PRIMARY KEY, \"%4\" varchar(20))").arg(schemaName).arg(tableName).arg(field1Name).arg(field2Name);
const auto createTable = QString("CREATE TABLE %1.%2 (\"%3\" int PRIMARY KEY, \"%4\" varchar(20))")
.arg(schemaName, tableName, field1Name, field2Name);
QVERIFY_SQL(q, exec(createTable));
QVERIFY(db.tables().contains(schemaName + '.' + tableName, Qt::CaseSensitive));
QVERIFY(db.tables().contains(qTableName(bumpyCase, __FILE__, db, false) + '.' +
qTableName("qtest", __FILE__, db, false), Qt::CaseSensitive));
QSqlField fld1(field1Name, QVariant::Int);
QSqlField fld2(field2Name, QVariant::String);
@ -1307,7 +1326,9 @@ void tst_QSqlDatabase::psql_escapedIdentifiers()
rec.append(fld1);
rec.append(fld2);
QVERIFY_SQL(q, exec(drv->sqlStatement(QSqlDriver::SelectStatement, db.driver()->escapeIdentifier(schemaName, QSqlDriver::TableName) + '.' + db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName), rec, false)));
QVERIFY_SQL(q, exec(drv->sqlStatement(QSqlDriver::SelectStatement,
schemaName + '.' + tableName,
rec, false)));
rec = q.record();
QCOMPARE(rec.count(), 2);
@ -1315,7 +1336,7 @@ void tst_QSqlDatabase::psql_escapedIdentifiers()
QCOMPARE(rec.fieldName(1), field2Name);
QCOMPARE(rec.field(0).type(), QVariant::Int);
q.exec(QString("DROP SCHEMA \"%1\" CASCADE").arg(schemaName));
q.exec(QString("DROP SCHEMA %1 CASCADE").arg(schemaName));
}
void tst_QSqlDatabase::psql_escapeBytea()
@ -2146,7 +2167,7 @@ void tst_QSqlDatabase::eventNotificationPSQL()
CHECK_DATABASE(db);
QSqlQuery query(db);
QString procedureName = qTableName("posteventProc", __FILE__, db);
const auto procedureName = qTableName("posteventProc", __FILE__, db, false);
QString payload = "payload";
QSqlDriver &driver=*(db.driver());
QVERIFY_SQL(driver, subscribeToNotification(procedureName));
@ -2170,21 +2191,22 @@ void tst_QSqlDatabase::eventNotificationSQLite()
QSKIP("QSQLITE specific test");
}
const QString tableName(qTableName("sqlitnotifytest", __FILE__, db));
const auto noEscapeTableName(qTableName("sqlitnotifytest", __FILE__, db, false));
tst_Databases::safeDropTable(db, tableName);
QSignalSpy notificationSpy(db.driver(), SIGNAL(notification(QString)));
QSignalSpy notificationSpyExt(db.driver(), SIGNAL(notification(QString,QSqlDriver::NotificationSource,QVariant)));
QSqlQuery q(db);
QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id INTEGER, realVal REAL)"));
db.driver()->subscribeToNotification(tableName);
db.driver()->subscribeToNotification(noEscapeTableName);
QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id, realVal) VALUES (1, 2.3)"));
QTRY_COMPARE(notificationSpy.count(), 1);
QTRY_COMPARE(notificationSpyExt.count(), 1);
QList<QVariant> arguments = notificationSpy.takeFirst();
QCOMPARE(arguments.at(0).toString(), tableName);
QCOMPARE(arguments.at(0).toString(), noEscapeTableName);
arguments = notificationSpyExt.takeFirst();
QCOMPARE(arguments.at(0).toString(), tableName);
db.driver()->unsubscribeFromNotification(tableName);
QCOMPARE(arguments.at(0).toString(), noEscapeTableName);
db.driver()->unsubscribeFromNotification(noEscapeTableName);
QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id, realVal) VALUES (1, 2.3)"));
QTRY_COMPARE(notificationSpy.count(), 0);
QTRY_COMPARE(notificationSpyExt.count(), 0);

View File

@ -1096,7 +1096,7 @@ void tst_QSqlQuery::record()
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();
const auto tst_record = qTableName("tst_record", __FILE__, db, false).toLower();
SETUP_RECORD_TABLE;
CHECK_RECORD;
q.clear();
@ -3742,15 +3742,13 @@ void tst_QSqlQuery::QTBUG_5251()
const QString timetest(qTableName("timetest", __FILE__, db));
tst_Databases::safeDropTable(db, timetest);
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE \"") + timetest + QStringLiteral("\" (t TIME)")));
QVERIFY_SQL(q, exec(QStringLiteral("INSERT INTO \"") + timetest +
QStringLiteral("\" VALUES ('1:2:3.666')")));
QVERIFY_SQL(q, exec(QStringLiteral("CREATE TABLE ") + timetest + QStringLiteral(" (t TIME)")));
QVERIFY_SQL(q, exec(QStringLiteral("INSERT INTO ") + timetest +
QStringLiteral(" VALUES ('1:2:3.666')")));
QSqlTableModel timetestModel(0,db);
timetestModel.setEditStrategy(QSqlTableModel::OnManualSubmit);
timetestModel.setTable(timetest);
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QVERIFY_SQL(timetestModel, select());
QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"), QString("01:02:03.666"));
@ -3759,8 +3757,8 @@ void tst_QSqlQuery::QTBUG_5251()
QVERIFY_SQL(timetestModel, submitAll());
QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"), QString("00:12:34.500"));
QVERIFY_SQL(q, exec(QStringLiteral("UPDATE \"") + timetest +
QStringLiteral("\" SET t = '0:11:22.33'")));
QVERIFY_SQL(q, exec(QStringLiteral("UPDATE ") + timetest +
QStringLiteral(" SET t = '0:11:22.33'")));
QVERIFY_SQL(timetestModel, select());
QCOMPARE(timetestModel.record(0).field(0).value().toTime().toString("HH:mm:ss.zzz"), QString("00:11:22.330"));

View File

@ -122,13 +122,13 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db)
QVERIFY_SQL( q, exec("insert into " + reltest5 + " values('mister', 'Mr')"));
if (testWhiteSpaceNames(db.driverName())) {
QString reltest6 = db.driver()->escapeIdentifier(qTableName("rel", __FILE__, db) + " test6", QSqlDriver::TableName);
const auto reltest6 = qTableName("rel test6", __FILE__, db);
QVERIFY_SQL( q, exec("create table " + reltest6 + " (id int not null primary key, " + db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName) +
" int, " + db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName) + " int)"));
QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(1, 1,9)"));
QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(2, 2,8)"));
QString reltest7 = db.driver()->escapeIdentifier(qTableName("rel", __FILE__, db) + " test7", QSqlDriver::TableName);
const auto reltest7 = qTableName("rel test7", __FILE__, db);
QVERIFY_SQL( q, exec("create table " + reltest7 + " (" + db.driver()->escapeIdentifier("city id", QSqlDriver::TableName) + " int not null primary key, " + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName) + " varchar(20))"));
QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(1, 'New York')"));
QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(2, 'Washington')"));
@ -170,8 +170,8 @@ void tst_QSqlRelationalTableModel::dropTestTables( QSqlDatabase db )
<< reltest3
<< reltest4
<< reltest5
<< (qTableName("rel", __FILE__, db) + " test6")
<< (qTableName( "rel", __FILE__, db) + " test7")
<< qTableName("rel test6", __FILE__, db)
<< qTableName("rel test7", __FILE__, db)
<< qTableName("CASETEST1", db)
<< qTableName("casetest1", db);
tst_Databases::safeDropTables( db, tableNames );
@ -1379,9 +1379,9 @@ void tst_QSqlRelationalTableModel::whiteSpaceInIdentifiers()
if (!testWhiteSpaceNames(db.driverName()))
QSKIP("White space test irrelevant for driver");
QSqlRelationalTableModel model(0, db);
model.setTable(db.driver()->escapeIdentifier(qTableName("rel", __FILE__, db) + " test6", QSqlDriver::TableName));
model.setTable(qTableName("rel test6", __FILE__, db));
model.setSort(0, Qt::DescendingOrder);
model.setRelation(1, QSqlRelation(db.driver()->escapeIdentifier(qTableName("rel", __FILE__, db) + " test7", QSqlDriver::TableName),
model.setRelation(1, QSqlRelation(qTableName("rel test7", __FILE__, db),
db.driver()->escapeIdentifier("city id", QSqlDriver::FieldName),
db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName)));
QVERIFY_SQL(model, select());
@ -1547,8 +1547,6 @@ void tst_QSqlRelationalTableModel::relationOnFirstColumn()
//modify the model data
QVERIFY_SQL(model, setData(model.index(0, 0), 40));
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QVERIFY_SQL(model, submit());
QVERIFY_SQL(model, setData(model.index(1, 0), 50));
QVERIFY_SQL(model, submit());

View File

@ -383,8 +383,6 @@ void tst_QSqlTableModel::selectRow()
q.exec("UPDATE " + tbl + " SET a = 'Qt' WHERE id = 1");
QCOMPARE(model.data(idx).toString(), QString("b"));
model.selectRow(1);
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QCOMPARE(model.data(idx).toString(), QString("Qt"));
// Check if selectRow() refreshes a changed row.
@ -441,8 +439,6 @@ void tst_QSqlTableModel::selectRowOverride()
// both rows should have changed
QCOMPARE(model.data(idx).toString(), QString("Qt"));
idx = model.index(2, 1);
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QCOMPARE(model.data(idx).toString(), QString("Qt"));
q.exec("DELETE FROM " + tbl);
@ -854,8 +850,6 @@ void tst_QSqlTableModel::insertRowFailure()
// populate 1 row
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::PostgreSQL && submitpolicy != QSqlTableModel::OnManualSubmit)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QVERIFY_SQL(model, insertRecord(0, values));
QVERIFY_SQL(model, submitAll());
QVERIFY_SQL(model, select());
@ -899,8 +893,6 @@ void tst_QSqlTableModel::insertRowFailure()
// restore empty table
model.revertAll();
QVERIFY_SQL(model, removeRow(0));
if (dbType == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QVERIFY_SQL(model, submitAll());
QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 0);
@ -2009,8 +2001,6 @@ void tst_QSqlTableModel::tableModifyWithBlank()
//Should be equivalent to QSqlQuery INSERT INTO... command)
QVERIFY_SQL(model, insertRow(0));
QVERIFY_SQL(model, setData(model.index(0,0),timeString));
if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL)
QEXPECT_FAIL("", "Currently broken for PostgreSQL due to case sensitivity problems - see QTBUG-65788", Abort);
QVERIFY_SQL(model, submitAll());
//set a filter on the table so the only record we get is the one we just made