Skip to content

Commit

Permalink
Always use string comparison in expressions for string fields
Browse files Browse the repository at this point in the history
Fixes #13204

(cherry-picked from 8a2e871)
  • Loading branch information
nyalldawson committed Jun 30, 2016
1 parent 482140b commit be8e4f9
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
9 changes: 6 additions & 3 deletions src/core/qgsexpression.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3751,9 +3751,11 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression *parent, const Q
{ {
return TVL_Unknown; return TVL_Unknown;
} }
else if ( isDoubleSafe( vL ) && isDoubleSafe( vR ) ) else if ( isDoubleSafe( vL ) && isDoubleSafe( vR ) &&
( vL.type() != QVariant::String || vR.type() != QVariant::String ) )
{ {
// do numeric comparison if both operators can be converted to numbers // do numeric comparison if both operators can be converted to numbers,
// and they aren't both string
double fL = getDoubleValue( vL, parent ); double fL = getDoubleValue( vL, parent );
ENSURE_NO_EVAL_ERROR; ENSURE_NO_EVAL_ERROR;
double fR = getDoubleValue( vR, parent ); double fR = getDoubleValue( vR, parent );
Expand All @@ -3780,7 +3782,8 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression *parent, const Q
else // both operators non-null else // both operators non-null
{ {
bool equal = false; bool equal = false;
if ( isDoubleSafe( vL ) && isDoubleSafe( vR ) ) if ( isDoubleSafe( vL ) && isDoubleSafe( vR ) &&
( vL.type() != QVariant::String || vR.type() != QVariant::String ) )
{ {
double fL = getDoubleValue( vL, parent ); double fL = getDoubleValue( vL, parent );
ENSURE_NO_EVAL_ERROR; ENSURE_NO_EVAL_ERROR;
Expand Down
18 changes: 18 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -299,6 +299,20 @@ class TestQgsExpression: public QObject
QTest::newRow( "'nan'='x'" ) << "'nan'='x'" << false << QVariant( 0 ); QTest::newRow( "'nan'='x'" ) << "'nan'='x'" << false << QVariant( 0 );
QTest::newRow( "'inf'='inf'" ) << "'inf'='inf'" << false << QVariant( 1 ); QTest::newRow( "'inf'='inf'" ) << "'inf'='inf'" << false << QVariant( 1 );
QTest::newRow( "'inf'='x'" ) << "'inf'='x'" << false << QVariant( 0 ); QTest::newRow( "'inf'='x'" ) << "'inf'='x'" << false << QVariant( 0 );
QTest::newRow( "'1.1'='1.1'" ) << "'1.1'='1.1'" << false << QVariant( 1 );
QTest::newRow( "'1.1'!='1.1'" ) << "'1.1'!='1.1'" << false << QVariant( 0 );
QTest::newRow( "'1.1'='1.10'" ) << "'1.1'='1.10'" << false << QVariant( 0 );
QTest::newRow( "'1.1'!='1.10'" ) << "'1.1'!='1.10'" << false << QVariant( 1 );
QTest::newRow( "1.1=1.10" ) << "1.1=1.10" << false << QVariant( 1 );
QTest::newRow( "1.1 != 1.10" ) << "1.1 != 1.10" << false << QVariant( 0 );
QTest::newRow( "'1.1'=1.1" ) << "'1.1'=1.1" << false << QVariant( 1 );
QTest::newRow( "'1.10'=1.1" ) << "'1.10'=1.1" << false << QVariant( 1 );
QTest::newRow( "1.1='1.10'" ) << "1.1='1.10'" << false << QVariant( 1 );
QTest::newRow( "'1.1'='1.10000'" ) << "'1.1'='1.10000'" << false << QVariant( 0 );
QTest::newRow( "'1E-23'='1E-23'" ) << "'1E-23'='1E-23'" << false << QVariant( 1 );
QTest::newRow( "'1E-23'!='1E-23'" ) << "'1E-23'!='1E-23'" << false << QVariant( 0 );
QTest::newRow( "'1E-23'='2E-23'" ) << "'1E-23'='2E-23'" << false << QVariant( 0 );
QTest::newRow( "'1E-23'!='2E-23'" ) << "'1E-23'!='2E-23'" << false << QVariant( 1 );


// is, is not // is, is not
QTest::newRow( "is null,null" ) << "null is null" << false << QVariant( 1 ); QTest::newRow( "is null,null" ) << "null is null" << false << QVariant( 1 );
Expand All @@ -309,6 +323,10 @@ class TestQgsExpression: public QObject
QTest::newRow( "is not int" ) << "1 is not 1" << false << QVariant( 0 ); QTest::newRow( "is not int" ) << "1 is not 1" << false << QVariant( 0 );
QTest::newRow( "is text" ) << "'x' is 'y'" << false << QVariant( 0 ); QTest::newRow( "is text" ) << "'x' is 'y'" << false << QVariant( 0 );
QTest::newRow( "is not text" ) << "'x' is not 'y'" << false << QVariant( 1 ); QTest::newRow( "is not text" ) << "'x' is not 'y'" << false << QVariant( 1 );
QTest::newRow( "'1.1' is '1.10'" ) << "'1.1' is '1.10'" << false << QVariant( 0 );
QTest::newRow( "'1.1' is '1.10000'" ) << "'1.1' is '1.10000'" << false << QVariant( 0 );
QTest::newRow( "1.1 is '1.10'" ) << "1.1 is '1.10'" << false << QVariant( 1 );
QTest::newRow( "'1.10' is 1.1" ) << "'1.10' is 1.1" << false << QVariant( 1 );


// logical // logical
QTest::newRow( "T or F" ) << "1=1 or 2=3" << false << QVariant( 1 ); QTest::newRow( "T or F" ) << "1=1 or 2=3" << false << QVariant( 1 );
Expand Down

0 comments on commit be8e4f9

Please sign in to comment.