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: Mark Brand <mabrand@mabrand.nl>
This commit is contained in:
parent
b009ed0cc8
commit
593b8f7f0b
@ -987,11 +987,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;
|
||||
|
@ -161,6 +161,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(); }
|
||||
@ -575,6 +577,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 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user