SQL/MySQL: Add support for Bit-Value Type - BIT
Add support for MYSQL_TYPE_BIT. Since the bitfield can be max 64bits, store it in a uint64_t. Writing such a value as MYSQL_TYPE_LONGLONG works as expected but receiving it needs a special handling. [ChangeLog][SQL][MySQL] Added handling for Bit-Value Type - BIT. Fixes: QTBUG-21326 Change-Id: Id20e3316caf6703b3bec8a828144494a20693fd8 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
18bd15a9ea
commit
30de1f74de
@ -215,6 +215,7 @@ static QMetaType qDecodeMYSQLType(enum_field_types mysqltype, uint flags)
|
||||
case MYSQL_TYPE_YEAR:
|
||||
type = QMetaType::Int;
|
||||
break;
|
||||
case MYSQL_TYPE_BIT:
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
type = (flags & UNSIGNED_FLAG) ? QMetaType::ULongLong : QMetaType::LongLong;
|
||||
break;
|
||||
@ -303,6 +304,11 @@ static bool qIsInteger(int t)
|
||||
|| t == QMetaType::LongLong || t == QMetaType::ULongLong;
|
||||
}
|
||||
|
||||
static inline bool qIsBitfield(enum_field_types type)
|
||||
{
|
||||
return type == MYSQL_TYPE_BIT;
|
||||
}
|
||||
|
||||
void QMYSQLResultPrivate::bindBlobs()
|
||||
{
|
||||
for (int i = 0; i < fields.size(); ++i) {
|
||||
@ -519,6 +525,20 @@ bool QMYSQLResult::fetchFirst()
|
||||
return fetch(0);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
qDecodeBitfield(const QMYSQLResultPrivate::QMyField &f, const char *outField)
|
||||
{
|
||||
// byte-aligned length
|
||||
const auto numBytes = (f.myField->length + 7) / 8;
|
||||
uint64_t val = 0;
|
||||
for (unsigned long i = 0; i < numBytes && outField; ++i) {
|
||||
uint64_t tmp = static_cast<uint8_t>(outField[i]);
|
||||
val <<= 8;
|
||||
val |= tmp;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
QVariant QMYSQLResult::data(int field)
|
||||
{
|
||||
Q_D(QMYSQLResult);
|
||||
@ -536,8 +556,9 @@ QVariant QMYSQLResult::data(int field)
|
||||
if (d->preparedQuery) {
|
||||
if (f.nullIndicator)
|
||||
return QVariant(f.type);
|
||||
|
||||
if (qIsInteger(f.type.id())) {
|
||||
if (qIsBitfield(f.myField->type)) {
|
||||
return QVariant::fromValue(qDecodeBitfield(f, f.outField));
|
||||
} else if (qIsInteger(f.type.id())) {
|
||||
QVariant variant(f.type, f.outField);
|
||||
// we never want to return char variants here, see QTBUG-53397
|
||||
if (f.type.id() == QMetaType::UChar)
|
||||
@ -569,6 +590,9 @@ QVariant QMYSQLResult::data(int field)
|
||||
return QVariant(f.type);
|
||||
}
|
||||
|
||||
if (qIsBitfield(f.myField->type))
|
||||
return QVariant::fromValue(qDecodeBitfield(f, d->row[field]));
|
||||
|
||||
fieldLength = mysql_fetch_lengths(d->result)[field];
|
||||
|
||||
if (f.type.id() != QMetaType::QByteArray)
|
||||
@ -677,6 +701,7 @@ bool QMYSQLResult::reset (const QString& query)
|
||||
for(int i = 0; i < numFields; i++) {
|
||||
MYSQL_FIELD* field = mysql_fetch_field_direct(d->result, i);
|
||||
d->fields[i].type = qDecodeMYSQLType(field->type, field->flags);
|
||||
d->fields[i].myField = field;
|
||||
}
|
||||
setAt(QSql::BeforeFirstRow);
|
||||
}
|
||||
@ -794,6 +819,7 @@ bool QMYSQLResult::nextResult()
|
||||
for (unsigned int i = 0; i < numFields; i++) {
|
||||
MYSQL_FIELD *field = mysql_fetch_field_direct(d->result, i);
|
||||
d->fields[i].type = qDecodeMYSQLType(field->type, field->flags);
|
||||
d->fields[i].myField = field;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4629,6 +4629,13 @@ void tst_QSqlQuery::integralTypesMysql()
|
||||
runIntegralTypesMysqlTest<qint64>(db, "bigIntTest", "BIGINT", withPreparedStatement);
|
||||
runIntegralTypesMysqlTest<quint64>(db, "unsignedBigIntTest", "BIGINT UNSIGNED",
|
||||
withPreparedStatement);
|
||||
runIntegralTypesMysqlTest<quint64>(db, "bitmask_7", "BIT(7)", withPreparedStatement, 0,
|
||||
(1LL << 7) - 1);
|
||||
runIntegralTypesMysqlTest<quint64>(db, "bitmask_31", "BIT(31)", withPreparedStatement, 0,
|
||||
(1LL << 31) - 1);
|
||||
runIntegralTypesMysqlTest<quint64>(db, "bitmask_33", "BIT(33)", withPreparedStatement, 0,
|
||||
(1LL << 33) - 1);
|
||||
runIntegralTypesMysqlTest<quint64>(db, "bitmask_64", "BIT(64)", withPreparedStatement);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user