PostgreSQL: Fix special floating point handling for 'float' types.
Introduce a template function to determine the special values via macro and use that for QVariant::Double and QMetaType::Float. Task-number: QTBUG-44381 Change-Id: I379dd82b22d467b0aebaa42f4f0f5c52472a5c47 Reviewed-by: Andy Shaw <andy.shaw@digia.com>
This commit is contained in:
parent
2f5c2ec12f
commit
916af48cff
@ -1248,6 +1248,23 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class FloatType>
|
||||||
|
inline void assignSpecialPsqlFloatValue(FloatType val, QString *target)
|
||||||
|
{
|
||||||
|
if (isnan(val)) {
|
||||||
|
*target = QLatin1String("'NaN'");
|
||||||
|
} else {
|
||||||
|
switch (isinf(val)) {
|
||||||
|
case 1:
|
||||||
|
*target = QLatin1String("'Infinity'");
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
*target = QLatin1String("'-Infinity'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
|
QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
|
||||||
{
|
{
|
||||||
Q_D(const QPSQLDriver);
|
Q_D(const QPSQLDriver);
|
||||||
@ -1255,7 +1272,7 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
|
|||||||
if (field.isNull()) {
|
if (field.isNull()) {
|
||||||
r = QLatin1String("NULL");
|
r = QLatin1String("NULL");
|
||||||
} else {
|
} else {
|
||||||
switch (field.type()) {
|
switch (int(field.type())) {
|
||||||
case QVariant::DateTime:
|
case QVariant::DateTime:
|
||||||
#ifndef QT_NO_DATESTRING
|
#ifndef QT_NO_DATESTRING
|
||||||
if (field.value().toDateTime().isValid()) {
|
if (field.value().toDateTime().isValid()) {
|
||||||
@ -1305,21 +1322,16 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
|
|||||||
qPQfreemem(data);
|
qPQfreemem(data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QVariant::Double: {
|
case QMetaType::Float:
|
||||||
double val = field.value().toDouble();
|
assignSpecialPsqlFloatValue(field.value().toFloat(), &r);
|
||||||
if (isnan(val))
|
if (r.isEmpty())
|
||||||
r = QLatin1String("'NaN'");
|
r = QSqlDriver::formatValue(field, trimStrings);
|
||||||
else {
|
break;
|
||||||
int res = isinf(val);
|
case QVariant::Double:
|
||||||
if (res == 1)
|
assignSpecialPsqlFloatValue(field.value().toDouble(), &r);
|
||||||
r = QLatin1String("'Infinity'");
|
if (r.isEmpty())
|
||||||
else if (res == -1)
|
r = QSqlDriver::formatValue(field, trimStrings);
|
||||||
r = QLatin1String("'-Infinity'");
|
|
||||||
else
|
|
||||||
r = QSqlDriver::formatValue(field, trimStrings);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
r = QSqlDriver::formatValue(field, trimStrings);
|
r = QSqlDriver::formatValue(field, trimStrings);
|
||||||
break;
|
break;
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
#include <QtSql/QtSql>
|
#include <QtSql/QtSql>
|
||||||
|
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
#include "../qsqldatabase/tst_databases.h"
|
#include "../qsqldatabase/tst_databases.h"
|
||||||
|
|
||||||
const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase()));
|
const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase()));
|
||||||
@ -159,6 +161,8 @@ private slots:
|
|||||||
void bindBool();
|
void bindBool();
|
||||||
void psql_bindWithDoubleColonCastOperator_data() { generic_data("QPSQL"); }
|
void psql_bindWithDoubleColonCastOperator_data() { generic_data("QPSQL"); }
|
||||||
void psql_bindWithDoubleColonCastOperator();
|
void psql_bindWithDoubleColonCastOperator();
|
||||||
|
void psql_specialFloatValues_data() { generic_data("QPSQL"); }
|
||||||
|
void psql_specialFloatValues();
|
||||||
void queryOnInvalidDatabase_data() { generic_data(); }
|
void queryOnInvalidDatabase_data() { generic_data(); }
|
||||||
void queryOnInvalidDatabase();
|
void queryOnInvalidDatabase();
|
||||||
void createQueryOnClosedDatabase_data() { generic_data(); }
|
void createQueryOnClosedDatabase_data() { generic_data(); }
|
||||||
@ -2437,6 +2441,38 @@ void tst_QSqlQuery::psql_bindWithDoubleColonCastOperator()
|
|||||||
QCOMPARE( q.executedQuery(), QString( "select sum((fld1 - fld2)::int) from " + tablename + " where id1 = 1 and id2 =2 and id3=3" ) );
|
QCOMPARE( q.executedQuery(), QString( "select sum((fld1 - fld2)::int) from " + tablename + " where id1 = 1 and id2 =2 and id3=3" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QSqlQuery::psql_specialFloatValues()
|
||||||
|
{
|
||||||
|
if (!std::numeric_limits<float>::has_quiet_NaN)
|
||||||
|
QSKIP("Platform does not have quiet_NaN");
|
||||||
|
if (!std::numeric_limits<float>::has_infinity)
|
||||||
|
QSKIP("Platform does not have infinity");
|
||||||
|
|
||||||
|
QFETCH( QString, dbName );
|
||||||
|
QSqlDatabase db = QSqlDatabase::database( dbName );
|
||||||
|
|
||||||
|
CHECK_DATABASE( db );
|
||||||
|
QSqlQuery query(db);
|
||||||
|
const QString tableName = qTableName("floattest", __FILE__, db);
|
||||||
|
QVERIFY_SQL( query, exec("create table " + tableName + " (value float)" ) );
|
||||||
|
QVERIFY_SQL(query, prepare("insert into " + tableName + " values(:value)") );
|
||||||
|
|
||||||
|
QVariantList data;
|
||||||
|
data << QVariant(double(42.42))
|
||||||
|
<< QVariant(std::numeric_limits<double>::quiet_NaN())
|
||||||
|
<< QVariant(std::numeric_limits<double>::infinity())
|
||||||
|
<< QVariant(float(42.42))
|
||||||
|
<< QVariant(std::numeric_limits<float>::quiet_NaN())
|
||||||
|
<< QVariant(std::numeric_limits<float>::infinity());
|
||||||
|
|
||||||
|
foreach (const QVariant &v, data) {
|
||||||
|
query.bindValue(":value", v);
|
||||||
|
QVERIFY_SQL( query, exec() );
|
||||||
|
}
|
||||||
|
|
||||||
|
QVERIFY_SQL( query, exec("drop table " + tableName) );
|
||||||
|
}
|
||||||
|
|
||||||
/* For task 157397: Using QSqlQuery with an invalid QSqlDatabase
|
/* For task 157397: Using QSqlQuery with an invalid QSqlDatabase
|
||||||
does not set the last error of the query.
|
does not set the last error of the query.
|
||||||
This test function will output some warnings, that's ok.
|
This test function will output some warnings, that's ok.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user