summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brand <mabrand@mabrand.nl>2012-10-30 09:51:25 (GMT)
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-11-13 10:54:58 (GMT)
commit8efd01e369d9427db38d9f3c524626607f4f114b (patch)
tree48c78a23fd0f866ef1dc38b67a9eaba482b368b2
parent8f090ffa0eb2949c9b335e42e2ce33bf519ad919 (diff)
downloadQt-8efd01e369d9427db38d9f3c524626607f4f114b.zip
Qt-8efd01e369d9427db38d9f3c524626607f4f114b.tar.gz
Qt-8efd01e369d9427db38d9f3c524626607f4f114b.tar.bz2
fix binding of bool type in mysql driver
MYSQL_TYPE_TINY should be used for binding bool input value. MYSQL_TYPE_LONG might be too big for bool, resulting in bools being saved in the database as int 127. The problem was not specific to the vendor's BOOL column type. http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html http://dev.mysql.com/doc/refman/5.0/en/c-api-prepared-statement-type-codes.html Added generic autotest to make sure that binding bool works. All drivers should pass this test. Task-number: QTBUG-27763 Change-Id: I4e69f8e3b32fffb702ec9fa8a80ff5c50dea954b Reviewed-by: Andy Shaw <andy.shaw@digia.com> Reviewed-by: Bill King <bill.king@nokia.com> (cherry picked from qt5/qtbase commit 593b8f7f0b35ddc424d8ccbd5df11fcf2442858e))
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.cpp7
-rw-r--r--tests/auto/qsqlquery/tst_qsqlquery.cpp35
2 files changed, 41 insertions, 1 deletions
diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index 3e00ce2..b820c86 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -991,11 +991,16 @@ bool QMYSQLResult::exec()
break; }
case QVariant::UInt:
case QVariant::Int:
- case QVariant::Bool:
currBind->buffer_type = MYSQL_TYPE_LONG;
currBind->buffer = data;
currBind->buffer_length = sizeof(int);
currBind->is_unsigned = (val.type() != QVariant::Int);
+ break;
+ case QVariant::Bool:
+ currBind->buffer_type = MYSQL_TYPE_TINY;
+ currBind->buffer = data;
+ currBind->buffer_length = sizeof(bool);
+ currBind->is_unsigned = false;
break;
case QVariant::Double:
currBind->buffer_type = MYSQL_TYPE_DOUBLE;
diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp
index 6923904..bdf7143 100644
--- a/tests/auto/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp
@@ -163,6 +163,8 @@ private slots:
void lastInsertId();
void lastQuery_data() { generic_data(); }
void lastQuery();
+ void bindBool_data() { generic_data(); }
+ void bindBool();
void bindWithDoubleColonCastOperator_data() { generic_data(); }
void bindWithDoubleColonCastOperator();
void queryOnInvalidDatabase_data() { generic_data(); }
@@ -572,6 +574,39 @@ void tst_QSqlQuery::mysqlOutValues()
QVERIFY_SQL( q, exec( "drop procedure " + qtestproc ) );
}
+void tst_QSqlQuery::bindBool()
+{
+ // QTBUG-27763: bool value got converted to int 127 by mysql driver becuase sizeof(bool) < sizeof(int).
+ // The problem was the way the bool value from the application was handled. It doesn't matter
+ // whether the table column type is BOOL or INT. Use INT here because all DBMSs have it and all
+ // should pass this test.
+ QFETCH( QString, dbName );
+ QSqlDatabase db = QSqlDatabase::database( dbName );
+ CHECK_DATABASE( db );
+ QSqlQuery q(db);
+
+ const QString tableName(qTableName( "bindBool", __FILE__ ));
+ q.exec("DROP TABLE " + tableName);
+ QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id INT, flag INT NOT NULL, PRIMARY KEY(id))"));
+
+ for (int i = 0; i < 2; ++i) {
+ bool flag = i;
+ q.prepare("INSERT INTO " + tableName + " (id, flag) VALUES(:id, :flag)");
+ q.bindValue(":id", i);
+ q.bindValue(":flag", flag);
+ QVERIFY_SQL(q, exec());
+ }
+
+ QVERIFY_SQL(q, exec("SELECT id, flag FROM " + tableName));
+ for (int i = 0; i < 2; ++i) {
+ bool flag = i;
+ QVERIFY_SQL(q, next());
+ QCOMPARE(q.value(0).toInt(), i);
+ QCOMPARE(q.value(1).toBool(), flag);
+ }
+ QVERIFY_SQL(q, exec("DROP TABLE " + tableName));
+}
+
void tst_QSqlQuery::oraOutValues()
{
QFETCH( QString, dbName );