From 948de0dc991e324cdfb01f2e84a6aadfbf8d737f Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 6 Apr 2009 15:49:40 +1000 Subject: Fixes: QSqlTableModel does not handle updates when one of the fields has a NULL value Task-number: 189093 --- src/sql/kernel/qsqldriver.cpp | 11 ++++++++--- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp index ddebe45..a995005 100644 --- a/src/sql/kernel/qsqldriver.cpp +++ b/src/sql/kernel/qsqldriver.cpp @@ -406,9 +406,14 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, break; case WhereStatement: if (preparedStatement) { - for (int i = 0; i < rec.count(); ++i) - s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append( - QLatin1String(" = ? AND ")); + for (int i = 0; i < rec.count(); ++i) { + s.append(escapeIdentifier(rec.fieldName(i), FieldName)); + if (rec.isNull(i)) + s.append(QLatin1String(" IS NULL")); + else + s.append(QLatin1String(" = ?")); + s.append(QLatin1String(" AND ")); + } } else { for (i = 0; i < rec.count(); ++i) { s.append(escapeIdentifier(rec.fieldName(i), FieldName)); diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index e10a0ca..51d5267 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -191,6 +191,10 @@ private slots: void sqlite_bindAndFetchUInt_data() { generic_data("QSQLITE3"); } void sqlite_bindAndFetchUInt(); + void sqlStatementUseIsNull_189093_data() { generic_data(); } + void sqlStatementUseIsNull_189093(); + + private: void createTestTables(QSqlDatabase db); void dropTestTables(QSqlDatabase db); @@ -363,6 +367,7 @@ void tst_QSqlDatabase::populateTestTables(QSqlDatabase db) QVERIFY_SQL(q, exec("insert into " + qTableName("qtest") + " (id, t_varchar, t_char, t_numeric) values (1, 'VarChar1', 'Char1', 2.2)")); QVERIFY_SQL(q, exec("insert into " + qTableName("qtest") + " (id, t_varchar, t_char, t_numeric) values (2, 'VarChar2', 'Char2', 3.3)")); QVERIFY_SQL(q, exec("insert into " + qTableName("qtest") + " (id, t_varchar, t_char, t_numeric) values (3, 'VarChar3', 'Char3', 4.4)")); + QVERIFY_SQL(q, exec("insert into " + qTableName("qtest") + " (id, t_varchar, t_char, t_numeric) values (4, 'VarChar4', NULL, NULL)")); } void tst_QSqlDatabase::initTestCase() @@ -2267,5 +2272,28 @@ void tst_QSqlDatabase::db2_valueCacheUpdate() QCOMPARE(c1.toString(), q.value(0).toString()); } +void tst_QSqlDatabase::sqlStatementUseIsNull_189093() +{ + // NULL = NULL is unknow, the sqlStatment must use IS NULL + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + // select a record with NULL value + QSqlQuery q(QString::null, db); + QVERIFY_SQL(q, exec("select * from " + qTableName("qtest") + " where id = 4")); + QVERIFY_SQL(q, next()); + + QSqlDriver *driver = db.driver(); + QVERIFY(driver); + + QString preparedStatment = driver->sqlStatement(QSqlDriver::WhereStatement, QString("qtest"), q.record(), true); + QCOMPARE(preparedStatment.count("IS NULL", Qt::CaseInsensitive), 2); + + QString statment = driver->sqlStatement(QSqlDriver::WhereStatement, QString("qtest"), q.record(), false); + QCOMPARE(statment.count("IS NULL", Qt::CaseInsensitive), 2); +} + + QTEST_MAIN(tst_QSqlDatabase) #include "tst_qsqldatabase.moc" -- cgit v0.12