Skip to content

Commit 1c76b93

Browse files
committedOct 20, 2015
Fix storing string representations of doubles in an int field
results in NULL rather than converting value to int
1 parent cac6201 commit 1c76b93

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed
 

‎src/core/qgsfield.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "qgsfield.h"
1818
#include "qgsfield_p.h"
19+
#include "qgis.h"
1920

2021
#include <QSettings>
2122
#include <QDataStream>
@@ -155,6 +156,30 @@ bool QgsField::convertCompatible( QVariant& v ) const
155156
return false;
156157
}
157158

159+
//String representations of doubles in QVariant will return false to convert( QVariant::Int )
160+
//work around this by first converting to double, and then checking whether the double is convertible to int
161+
if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
162+
{
163+
bool ok = false;
164+
double dbl = v.toDouble( &ok );
165+
if ( !ok )
166+
{
167+
//couldn't convert to number
168+
v = QVariant( d->type );
169+
return false;
170+
}
171+
172+
double round = qgsRound( dbl );
173+
if ( round > INT_MAX || round < -INT_MAX )
174+
{
175+
//double too large to fit in int
176+
v = QVariant( d->type );
177+
return false;
178+
}
179+
v = QVariant( qRound( dbl ) );
180+
return true;
181+
}
182+
158183
if ( !v.convert( d->type ) )
159184
{
160185
v = QVariant( d->type );

‎tests/src/core/testqgsfield.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,52 @@ void TestQgsField::convertCompatible()
256256

257257
//test special rules
258258

259-
//conversion of longlong to int
259+
//conversion of double to int
260260
QgsField intField( "int", QVariant::Int, "int" );
261+
//small double, should be rounded
262+
QVariant smallDouble( 45.7 );
263+
QVERIFY( intField.convertCompatible( smallDouble ) );
264+
QCOMPARE( smallDouble.type(), QVariant::Int );
265+
QCOMPARE( smallDouble, QVariant( 46 ) );
266+
QVariant negativeSmallDouble( -9345.754534525235235 );
267+
QVERIFY( intField.convertCompatible( negativeSmallDouble ) );
268+
QCOMPARE( negativeSmallDouble.type(), QVariant::Int );
269+
QCOMPARE( negativeSmallDouble, QVariant( -9346 ) );
270+
//large double, cannot be converted
271+
QVariant largeDouble( 9999999999.99 );
272+
QVERIFY( !intField.convertCompatible( largeDouble ) );
273+
QCOMPARE( largeDouble.type(), QVariant::Int );
274+
QVERIFY( largeDouble.isNull( ) );
275+
276+
//conversion of string double value to int
277+
QVariant notNumberString( "notanumber" );
278+
QVERIFY( !intField.convertCompatible( notNumberString ) );
279+
QCOMPARE( notNumberString.type(), QVariant::Int );
280+
QVERIFY( notNumberString.isNull( ) );
281+
//small double, should be rounded
282+
QVariant smallDoubleString( "45.7" );
283+
QVERIFY( intField.convertCompatible( smallDoubleString ) );
284+
QCOMPARE( smallDoubleString.type(), QVariant::Int );
285+
QCOMPARE( smallDoubleString, QVariant( 46 ) );
286+
QVariant negativeSmallDoubleString( "-9345.754534525235235" );
287+
QVERIFY( intField.convertCompatible( negativeSmallDoubleString ) );
288+
QCOMPARE( negativeSmallDoubleString.type(), QVariant::Int );
289+
QCOMPARE( negativeSmallDoubleString, QVariant( -9346 ) );
290+
//large double, cannot be converted
291+
QVariant largeDoubleString( "9999999999.99" );
292+
QVERIFY( !intField.convertCompatible( largeDoubleString ) );
293+
QCOMPARE( largeDoubleString.type(), QVariant::Int );
294+
QVERIFY( largeDoubleString.isNull( ) );
295+
296+
//conversion of longlong to int
261297
QVariant longlong( 99999999999999999LL );
262298
QVERIFY( !intField.convertCompatible( longlong ) );
263299
QCOMPARE( longlong.type(), QVariant::Int );
264300
QVERIFY( longlong.isNull( ) );
301+
QVariant smallLonglong( 99LL );
302+
QVERIFY( intField.convertCompatible( smallLonglong ) );
303+
QCOMPARE( smallLonglong.type(), QVariant::Int );
304+
QCOMPARE( smallLonglong, QVariant( 99 ) );
265305
//conversion of longlong to longlong field
266306
QgsField longlongField( "long", QVariant::LongLong, "longlong" );
267307
longlong = QVariant( 99999999999999999LL );

0 commit comments

Comments
 (0)