diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-12-22 15:09:23 +0100 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2022-01-12 17:41:07 +0100 |
commit | 999d856bc8569455c21850dc524a595e6b6f52b6 (patch) | |
tree | 8ed959c57f0fcbf527324204df1b00e0b76d6074 /src/sql | |
parent | 66f0149693c810a512001d9d4df89b6f9d7a9327 (diff) |
Adapt SQL drivers to Qt 6 change of QVariant::isNull
In Qt 5, QVariant::isNull returned true if either the variant didn't
contain a value, or if the value was of a nullable type where the type's
isNull member function returned true.
In Qt 6, QVariant::isNull only returns true for variants that don't
contain a value; if the value contained is e.g. a null-QString or
QDateTime, then QVariant::isNull returns false.
This change requires a follow up in the SQL drivers, which must
still treat null-values the same as null-variants, lest they write data
into the data base.
Add a static helper to QSqlResultPrivate that implements isNull-checking
of variants that contain a nullable type relevant for Sql, and add a
test case to the QSqlQuery test that exercises that code.
Pick-to: 6.2 6.3
Fixes: QTBUG-99408
Fixes: QTBUG-98471
Change-Id: I08b74a33aa3235c37d974f182da1f2bdcfd8217e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/sql')
-rw-r--r-- | src/sql/kernel/qsqlresult.cpp | 34 | ||||
-rw-r--r-- | src/sql/kernel/qsqlresult_p.h | 2 |
2 files changed, 34 insertions, 2 deletions
diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index a948abb13e..568520cd5c 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -47,7 +47,9 @@ #include "qsqlfield.h" #include "qsqlrecord.h" #include "qsqlresult_p.h" +#include "quuid.h" #include "qvariant.h" +#include "qdatetime.h" #include "private/qsqldriver_p.h" #include <QDebug> @@ -619,6 +621,31 @@ bool QSqlResult::prepare(const QString& query) return true; // fake prepares should always succeed } +bool QSqlResultPrivate::isVariantNull(const QVariant &variant) +{ + if (variant.isNull()) + return true; + + switch (variant.typeId()) { + case qMetaTypeId<QString>(): + return static_cast<const QString*>(variant.constData())->isNull(); + case qMetaTypeId<QByteArray>(): + return static_cast<const QByteArray*>(variant.constData())->isNull(); + case qMetaTypeId<QDateTime>(): + return static_cast<const QDateTime*>(variant.constData())->isNull(); + case qMetaTypeId<QDate>(): + return static_cast<const QDate*>(variant.constData())->isNull(); + case qMetaTypeId<QTime>(): + return static_cast<const QTime*>(variant.constData())->isNull(); + case qMetaTypeId<QUuid>(): + return static_cast<const QUuid*>(variant.constData())->isNull(); + default: + break; + } + + return false; +} + /*! Executes the query, returning true if successful; otherwise returns false. @@ -639,7 +666,10 @@ bool QSqlResult::exec() holder = d->holders.at(i).holderName; val = d->values.value(d->indexes.value(holder).value(0,-1)); QSqlField f(QLatin1String(""), val.metaType()); - f.setValue(val); + if (QSqlResultPrivate::isVariantNull(val)) + f.setValue(QVariant()); + else + f.setValue(val); query = query.replace(d->holders.at(i).holderPos, holder.length(), driver()->formatValue(f)); } @@ -653,7 +683,7 @@ bool QSqlResult::exec() continue; QVariant var = d->values.value(idx); QSqlField f(QLatin1String(""), var.metaType()); - if (var.isNull()) + if (QSqlResultPrivate::isVariantNull(var)) f.clear(); else f.setValue(var); diff --git a/src/sql/kernel/qsqlresult_p.h b/src/sql/kernel/qsqlresult_p.h index 672f3ac59b..4aa2f2e838 100644 --- a/src/sql/kernel/qsqlresult_p.h +++ b/src/sql/kernel/qsqlresult_p.h @@ -133,6 +133,8 @@ public: bool active = false; bool isSel = false; bool forwardOnly = false; + + static bool isVariantNull(const QVariant &variant); }; QT_END_NAMESPACE |