@@ -86,24 +86,28 @@ Q_DECLARE_METATYPE( TVL )
86
86
// /////////////////////////////////////////////
87
87
// QVariant checks and conversions
88
88
89
- inline bool isInt( const QVariant& v ) { return v.type () == QVariant::Int; }
90
- inline bool isDouble ( const QVariant& v ) { return v.type () == QVariant::Double; }
91
- inline bool isNumeric ( const QVariant& v ) { return v.type () == QVariant::Int || v.type () == QVariant::Double; }
92
- inline bool isString ( const QVariant& v ) { return v.type () == QVariant::String; }
93
- inline bool isNull ( const QVariant& v ) { return v.type () == QVariant::Invalid; }
94
- inline bool isLogic ( const QVariant& v ) { return v.canConvert <TVL>(); }
95
- inline bool isNumericOrNull ( const QVariant& v ) { return v.type () == QVariant::Int || v.type () == QVariant::Double; }
96
-
97
- inline int qvInt ( const QVariant& v ) { return v.toInt (); }
98
- inline double qvDouble ( const QVariant& v ) { return v.toDouble (); }
99
- inline QString qvString ( const QVariant& v ) { return v.toString (); }
100
- inline TVL qvLogic ( const QVariant& v ) { return v.value <TVL>(); }
89
+ inline bool isIntSafe( const QVariant& v )
90
+ {
91
+ if ( v.type () == QVariant::Int || v.canConvert <TVL>() ) return true ;
92
+ if ( v.type () == QVariant::Double ) return false ;
93
+ if ( v.type () == QVariant::String ) { bool ok; v.toString ().toInt ( &ok ); return ok; }
94
+ return false ;
95
+ }
96
+ inline bool isDoubleSafe ( const QVariant& v )
97
+ {
98
+ if ( v.type () == QVariant::Double || v.type () == QVariant::Int || v.canConvert <TVL>() ) return true ;
99
+ if ( v.type () == QVariant::String ) { bool ok; v.toString ().toDouble ( &ok ); return ok; }
100
+ return false ;
101
+ }
102
+
103
+ inline bool isNull ( const QVariant& v ) { return v.type () == QVariant::Invalid || ( v.canConvert <TVL>() && v.value <TVL>().val == TVL::Unknown ); }
104
+ inline bool isTVL ( const QVariant & v ) { return v.canConvert <TVL>(); }
101
105
102
106
// /////////////////////////////////////////////
103
107
// evaluation error macros
104
108
105
- #define ENSURE_NO_EVAL_ERROR { if (! parent->mEvalErrorString . isNull ()) return QVariant (); }
106
- #define SET_EVAL_ERROR (x ) { parent->mEvalErrorString = x ; return QVariant (); }
109
+ #define ENSURE_NO_EVAL_ERROR { if (parent->hasEvalError ()) return QVariant (); }
110
+ #define SET_EVAL_ERROR (x ) { parent->setEvalErrorString (x) ; return QVariant (); }
107
111
108
112
// /////////////////////////////////////////////
109
113
// operators
@@ -124,131 +128,159 @@ const char* QgsExpression::UnaryOperatorText[] =
124
128
// /////////////////////////////////////////////
125
129
// functions
126
130
127
- static int getIntArg ( int i, const QVariantList& values, QgsExpression* parent )
131
+ // implicit conversion to string
132
+ static QString getStringValue ( const QVariant& value, QgsExpression* )
128
133
{
129
- QVariant v = values.at ( i );
130
- if ( !isInt ( v ) )
134
+ if ( value.canConvert <TVL>() )
135
+ {
136
+ TVL::Value tvl = value.value <TVL>().val ;
137
+ Q_ASSERT ( tvl != TVL::Unknown ); // null should be handled before calling this function
138
+ return ( tvl == TVL::True ? " 1" : " 0" );
139
+ }
140
+ return value.toString ();
141
+ }
142
+
143
+ static double getDoubleValue ( const QVariant& value, QgsExpression* parent )
144
+ {
145
+ if ( value.canConvert <TVL>() )
146
+ {
147
+ TVL::Value tvl = value.value <TVL>().val ;
148
+ Q_ASSERT ( tvl != TVL::Unknown ); // null should be handled before calling this function
149
+ return ( tvl == TVL::True ? 1 : 0 );
150
+ }
151
+
152
+ bool ok;
153
+ double x = value.toDouble ( &ok );
154
+ if ( !ok )
131
155
{
132
- parent->setEvalErrorString ( " Function needs integer value " );
156
+ parent->setEvalErrorString ( QString ( " Cannot convert '%1' to double " ). arg ( value. toString () ) );
133
157
return 0 ;
134
158
}
135
- return v. toInt () ;
159
+ return x ;
136
160
}
137
161
138
- static double getNumericArg ( int i, const QVariantList& values , QgsExpression* parent )
162
+ static int getIntValue ( const QVariant& value , QgsExpression* parent )
139
163
{
140
- QVariant v = values.at ( i );
141
- if ( !isNumeric ( v ) )
164
+ if ( value.canConvert <TVL>() )
142
165
{
143
- parent->setEvalErrorString ( " Function needs numeric value" );
144
- return NAN;
166
+ TVL::Value tvl = value.value <TVL>().val ;
167
+ Q_ASSERT ( tvl != TVL::Unknown ); // null should be handled before calling this function
168
+ return ( tvl == TVL::True ? 1 : 0 );
145
169
}
146
- return v.toDouble ();
170
+
171
+ bool ok;
172
+ int x = value.toInt ( &ok );
173
+ if ( !ok )
174
+ {
175
+ parent->setEvalErrorString ( QString ( " Cannot convert '%1' to int" ).arg ( value.toString () ) );
176
+ return 0 ;
177
+ }
178
+ return x;
147
179
}
148
180
149
- static QString getStringArg ( int i, const QVariantList& values, QgsExpression* parent )
181
+
182
+ // this handles also NULL values
183
+ static TVL getTVLValue ( const QVariant& value, QgsExpression* parent )
150
184
{
151
- QVariant v = values.at ( i );
152
- if ( !isString ( v ) )
185
+ if ( isTVL ( value ) )
186
+ return value.value <TVL>();
187
+
188
+ // we need to convert to TVL
189
+ if ( value.type () == QVariant::Invalid )
190
+ return TVL ();
191
+
192
+ bool ok;
193
+ double x = value.toDouble ( &ok );
194
+ if ( !ok )
153
195
{
154
- parent->setEvalErrorString ( " Function needs string value " );
155
- return QString ();
196
+ parent->setEvalErrorString ( QString ( " Cannot convert '%1' to boolean " ). arg ( value. toString () ) );
197
+ return TVL ();
156
198
}
157
- return v. toString ( );
199
+ return x != 0 ? TVL ( true ) : TVL ( false );
158
200
}
159
201
202
+ // ////
203
+
160
204
QVariant fcnSqrt ( const QVariantList& values, QgsFeature* /* f*/ , QgsExpression* parent )
161
205
{
162
- double x = getNumericArg ( 0 , values , parent );
163
- return isnan ( x ) ? QVariant () : QVariant ( sqrt ( x ) );
206
+ double x = getDoubleValue ( values. at ( 0 ) , parent );
207
+ return QVariant ( sqrt ( x ) );
164
208
}
165
209
QVariant fcnSin ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
166
210
{
167
- double x = getNumericArg ( 0 , values , parent );
168
- return isnan ( x ) ? QVariant () : QVariant ( sin ( x ) );
211
+ double x = getDoubleValue ( values. at ( 0 ) , parent );
212
+ return QVariant ( sin ( x ) );
169
213
}
170
214
QVariant fcnCos ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
171
215
{
172
- double x = getNumericArg ( 0 , values , parent );
173
- return isnan ( x ) ? QVariant () : QVariant ( cos ( x ) );
216
+ double x = getDoubleValue ( values. at ( 0 ) , parent );
217
+ return QVariant ( cos ( x ) );
174
218
}
175
219
QVariant fcnTan ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
176
220
{
177
- double x = getNumericArg ( 0 , values , parent );
178
- return isnan ( x ) ? QVariant () : QVariant ( tan ( x ) );
221
+ double x = getDoubleValue ( values. at ( 0 ) , parent );
222
+ return QVariant ( tan ( x ) );
179
223
}
180
224
QVariant fcnAsin ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
181
225
{
182
- double x = getNumericArg ( 0 , values , parent );
183
- return isnan ( x ) ? QVariant () : QVariant ( asin ( x ) );
226
+ double x = getDoubleValue ( values. at ( 0 ) , parent );
227
+ return QVariant ( asin ( x ) );
184
228
}
185
229
QVariant fcnAcos ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
186
230
{
187
- double x = getNumericArg ( 0 , values , parent );
188
- return isnan ( x ) ? QVariant () : QVariant ( acos ( x ) );
231
+ double x = getDoubleValue ( values. at ( 0 ) , parent );
232
+ return QVariant ( acos ( x ) );
189
233
}
190
234
QVariant fcnAtan ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
191
235
{
192
- double x = getNumericArg ( 0 , values , parent );
193
- return isnan ( x ) ? QVariant () : QVariant ( atan ( x ) );
236
+ double x = getDoubleValue ( values. at ( 0 ) , parent );
237
+ return QVariant ( atan ( x ) );
194
238
}
195
239
QVariant fcnAtan2 ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
196
240
{
197
- double y = getNumericArg ( 0 , values, parent );
198
- double x = getNumericArg ( 1 , values, parent );
199
- if ( isnan ( y ) || isnan ( x ) ) return QVariant ();
241
+ double y = getDoubleValue ( values.at ( 0 ), parent );
242
+ double x = getDoubleValue ( values.at ( 1 ), parent );
200
243
return QVariant ( atan2 ( y, x ) );
201
244
}
202
- QVariant fcnToInt ( const QVariantList& values, QgsFeature* , QgsExpression* /* parent*/ )
245
+ QVariant fcnToInt ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
203
246
{
204
- QVariant v = values.at ( 0 );
205
- if ( v.type () == QVariant::Invalid ) return QVariant ();
206
- return QVariant ( v.toInt () );
247
+ return QVariant ( getIntValue ( values.at ( 0 ), parent ) );
207
248
}
208
- QVariant fcnToReal ( const QVariantList& values, QgsFeature* , QgsExpression* /* parent*/ )
249
+ QVariant fcnToReal ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
209
250
{
210
- QVariant v = values.at ( 0 );
211
- if ( v.type () == QVariant::Invalid ) return QVariant ();
212
- return QVariant ( v.toDouble () );
251
+ return QVariant ( getDoubleValue ( values.at ( 0 ), parent ) );
213
252
}
214
- QVariant fcnToString ( const QVariantList& values, QgsFeature* , QgsExpression* /* parent*/ )
253
+ QVariant fcnToString ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
215
254
{
216
- QVariant v = values.at ( 0 );
217
- if ( v.type () == QVariant::Invalid ) return QVariant ();
218
- return QVariant ( v.toString () );
255
+ return QVariant ( getStringValue ( values.at ( 0 ), parent ) );
219
256
}
220
257
QVariant fcnLower ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
221
258
{
222
- QString str = getStringArg ( 0 , values, parent );
223
- if ( str.isNull () ) return QVariant (); // error or null string
259
+ QString str = getStringValue ( values.at ( 0 ), parent );
224
260
return QVariant ( str.toLower () );
225
261
}
226
262
QVariant fcnUpper ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
227
263
{
228
- QString str = getStringArg ( 0 , values, parent );
229
- if ( str.isNull () ) return QVariant (); // error or null string
264
+ QString str = getStringValue ( values.at ( 0 ), parent );
230
265
return QVariant ( str.toUpper () );
231
266
}
232
267
QVariant fcnLength ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
233
268
{
234
- QString str = getStringArg ( 0 , values, parent );
235
- if ( str.isNull () ) return QVariant (); // error or null string
269
+ QString str = getStringValue ( values.at ( 0 ), parent );
236
270
return QVariant ( str.length () );
237
271
}
238
272
QVariant fcnReplace ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
239
273
{
240
- QString str = getStringArg ( 0 , values, parent );
241
- QString before = getStringArg ( 1 , values, parent );
242
- QString after = getStringArg ( 2 , values, parent );
243
- if ( str.isNull () || before.isNull () || after.isNull () ) return QVariant (); // error or null string
274
+ QString str = getStringValue ( values.at ( 0 ), parent );
275
+ QString before = getStringValue ( values.at ( 1 ), parent );
276
+ QString after = getStringValue ( values.at ( 2 ), parent );
244
277
return QVariant ( str.replace ( before, after ) );
245
278
}
246
279
QVariant fcnRegexpReplace ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
247
280
{
248
- QString str = getStringArg ( 0 , values, parent );
249
- QString regexp = getStringArg ( 1 , values, parent );
250
- QString after = getStringArg ( 2 , values, parent );
251
- if ( str.isNull () || regexp.isNull () || after.isNull () ) return QVariant (); // error or null string
281
+ QString str = getStringValue ( values.at ( 0 ), parent );
282
+ QString regexp = getStringValue ( values.at ( 1 ), parent );
283
+ QString after = getStringValue ( values.at ( 2 ), parent );
252
284
253
285
QRegExp re ( regexp );
254
286
if ( !re.isValid () )
@@ -260,12 +292,9 @@ QVariant fcnRegexpReplace( const QVariantList& values, QgsFeature* , QgsExpressi
260
292
}
261
293
QVariant fcnSubstr ( const QVariantList& values, QgsFeature* , QgsExpression* parent )
262
294
{
263
- QString str = getStringArg ( 0 , values, parent );
264
- if ( str.isNull () ) return QVariant (); // error or null string
265
- int from = getIntArg ( 1 , values, parent );
266
- if ( parent->hasEvalError () ) return QVariant ();
267
- int len = getIntArg ( 2 , values, parent );
268
- if ( parent->hasEvalError () ) return QVariant ();
295
+ QString str = getStringValue ( values.at ( 0 ), parent );
296
+ int from = getIntValue ( values.at ( 1 ), parent );
297
+ int len = getIntValue ( values.at ( 2 ), parent );
269
298
return QVariant ( str.mid ( from -1 , len ) );
270
299
}
271
300
@@ -298,7 +327,7 @@ QVariant fcnY( const QVariantList& , QgsFeature* f, QgsExpression* )
298
327
299
328
static QVariant pointAt ( const QVariantList& values, QgsFeature* f, QgsExpression* parent ) // helper function
300
329
{
301
- int idx = getIntArg ( 0 , values , parent );
330
+ int idx = getIntValue ( values. at ( 0 ) , parent );
302
331
ENSURE_GEOM_TYPE ( f, g, QGis::Line );
303
332
QgsPolyline polyline = g->asPolyline ();
304
333
if ( idx < 0 )
@@ -532,25 +561,24 @@ QVariant QgsExpression::NodeUnaryOperator::eval( QgsExpression* parent, QgsFeatu
532
561
switch ( mOp )
533
562
{
534
563
case uoNot:
535
- if ( isLogic ( val ) )
536
- val. setValue ( ! qvLogic ( val ) );
537
- else
538
- SET_EVAL_ERROR ( " NOT applicable only on boolean " );
539
- break ;
564
+ {
565
+ TVL tvl = getTVLValue ( val, parent );
566
+ ENSURE_NO_EVAL_ERROR;
567
+ return QVariant::fromValue ( ! tvl );
568
+ }
540
569
541
570
case uoMinus:
542
- if ( isInt ( val ) )
543
- val. setValue ( - qvInt ( val ) );
544
- else if ( isDouble ( val ) )
545
- val. setValue ( - qvDouble ( val ) );
571
+ if ( isIntSafe ( val ) )
572
+ return QVariant ( - getIntValue ( val, parent ) );
573
+ else if ( isDoubleSafe ( val ) )
574
+ return QVariant ( - getDoubleValue ( val, parent ) );
546
575
else
547
576
SET_EVAL_ERROR ( " Unary minus only for numeric values." );
548
577
break ;
549
578
default :
550
579
Q_ASSERT ( 0 && " unknown unary operation" );
551
580
}
552
-
553
- return val;
581
+ return QVariant ();
554
582
}
555
583
556
584
bool QgsExpression::NodeUnaryOperator::prepare ( QgsExpression* parent, const QgsFieldMap& fields )
@@ -581,37 +609,47 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression* parent, QgsFeat
581
609
case boMod:
582
610
if ( isNull ( vL ) || isNull ( vR ) )
583
611
return QVariant ();
584
- else if ( isNumeric ( vL ) && isNumeric ( vR ) )
612
+ else if ( isIntSafe ( vL ) && isIntSafe ( vR ) )
585
613
{
586
- if ( mOp == boDiv && qvDouble ( vR ) == 0 )
587
- return QVariant (); // silently handle division by zero and return NULL
588
- if ( isInt ( vL ) && isInt ( vR ) )
589
- return QVariant ( computeInt ( qvInt ( vL ), qvInt ( vR ) ) );
590
- else
591
- return QVariant ( computeDouble ( qvDouble ( vL ), qvDouble ( vR ) ) );
614
+ // both are integers - let's use integer arithmetics
615
+ int iL = getIntValue ( vL, parent ); ENSURE_NO_EVAL_ERROR;
616
+ int iR = getIntValue ( vR, parent ); ENSURE_NO_EVAL_ERROR;
617
+ if ( mOp == boDiv && iR == 0 ) return QVariant (); // silently handle division by zero and return NULL
618
+ return QVariant ( computeInt ( iL, iR ) );
592
619
}
593
620
else
594
- SET_EVAL_ERROR ( " Arithmetic possible only with numeric values" );
621
+ {
622
+ // general floating point arithmetic
623
+ double fL = getDoubleValue ( vL, parent ); ENSURE_NO_EVAL_ERROR;
624
+ double fR = getDoubleValue ( vR, parent ); ENSURE_NO_EVAL_ERROR;
625
+ if ( mOp == boDiv && fR == 0 )
626
+ return QVariant (); // silently handle division by zero and return NULL
627
+ return QVariant ( computeDouble ( fL , fR ) );
628
+ }
595
629
596
630
case boPow:
597
631
if ( isNull ( vL ) || isNull ( vR ) )
598
632
return QVariant ();
599
- else if ( isNumeric ( vL ) && isNumeric ( vR ) )
600
- return QVariant ( pow ( qvDouble ( vL ), qvDouble ( vR ) ) );
601
633
else
602
- SET_EVAL_ERROR ( " Arithmetic possible only with numeric values" );
634
+ {
635
+ double fL = getDoubleValue ( vL, parent ); ENSURE_NO_EVAL_ERROR;
636
+ double fR = getDoubleValue ( vR, parent ); ENSURE_NO_EVAL_ERROR;
637
+ return QVariant ( pow ( fL , fR ) );
638
+ }
603
639
604
640
case boAnd:
605
- if ( isLogic ( vL ) && isLogic ( vR ) )
606
- return QVariant::fromValue ( qvLogic ( vL ) & qvLogic ( vR ) );
607
- else
608
- SET_EVAL_ERROR ( " AND applicable only on boolean" );
641
+ {
642
+ TVL tvlL = getTVLValue ( vL, parent ), tvlR = getTVLValue ( vR, parent );
643
+ ENSURE_NO_EVAL_ERROR;
644
+ return QVariant::fromValue ( tvlL & tvlR );
645
+ }
609
646
610
647
case boOr:
611
- if ( isLogic ( vL ) && isLogic ( vR ) )
612
- return QVariant::fromValue ( qvLogic ( vL ) | qvLogic ( vR ) );
613
- else
614
- SET_EVAL_ERROR ( " OR applicable only on boolean" );
648
+ {
649
+ TVL tvlL = getTVLValue ( vL, parent ), tvlR = getTVLValue ( vR, parent );
650
+ ENSURE_NO_EVAL_ERROR;
651
+ return QVariant::fromValue ( tvlL | tvlR );
652
+ }
615
653
616
654
case boEQ:
617
655
case boNE:
@@ -623,18 +661,21 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression* parent, QgsFeat
623
661
{
624
662
return TVL_Unknown;
625
663
}
626
- else if ( isNumeric ( vL ) && isNumeric ( vR ) )
664
+ else if ( isDoubleSafe ( vL ) && isDoubleSafe ( vR ) )
627
665
{
628
- double diff = qvDouble ( vL ) - qvDouble ( vR );
629
- return compare ( diff ) ? TVL_True : TVL_False;
666
+ // do numeric comparison if both operators can be converted to numbers
667
+ double fL = getDoubleValue ( vL, parent ); ENSURE_NO_EVAL_ERROR;
668
+ double fR = getDoubleValue ( vR, parent ); ENSURE_NO_EVAL_ERROR;
669
+ return compare ( fL - fR ) ? TVL_True : TVL_False;
630
670
}
631
- else if ( isString ( vL ) && isString ( vR ) )
671
+ else
632
672
{
633
- int diff = QString::compare ( qvString ( vL ), qvString ( vR ) );
673
+ // do string comparison otherwise
674
+ QString sL = getStringValue ( vL, parent ); ENSURE_NO_EVAL_ERROR;
675
+ QString sR = getStringValue ( vR, parent ); ENSURE_NO_EVAL_ERROR;
676
+ int diff = QString::compare ( sL , sR );
634
677
return compare ( diff ) ? TVL_True : TVL_False;
635
678
}
636
- else
637
- SET_EVAL_ERROR ( " Invalid arguments for comparison" );
638
679
639
680
case boIs:
640
681
case boIsNot:
@@ -645,12 +686,18 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression* parent, QgsFeat
645
686
else // both operators non-null
646
687
{
647
688
bool equal = false ;
648
- if ( isNumeric ( vL ) && isNumeric ( vR ) )
649
- equal = qvDouble ( vL ) == qvDouble ( vR );
650
- else if ( isString ( vL ) && isString ( vR ) )
651
- equal = QString::compare ( qvString ( vL ), qvString ( vR ) ) == 0 ;
689
+ if ( isDoubleSafe ( vL ) && isDoubleSafe ( vR ) )
690
+ {
691
+ double fL = getDoubleValue ( vL, parent ); ENSURE_NO_EVAL_ERROR;
692
+ double fR = getDoubleValue ( vR, parent ); ENSURE_NO_EVAL_ERROR;
693
+ equal = fL == fR ;
694
+ }
652
695
else
653
- SET_EVAL_ERROR ( " Invalid arguments for comparison" );
696
+ {
697
+ QString sL = getStringValue ( vL, parent ); ENSURE_NO_EVAL_ERROR;
698
+ QString sR = getStringValue ( vR, parent ); ENSURE_NO_EVAL_ERROR;
699
+ equal = QString::compare ( sL , sR ) == 0 ;
700
+ }
654
701
if ( equal )
655
702
return mOp == boIs ? TVL_True : TVL_False;
656
703
else
@@ -662,9 +709,10 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression* parent, QgsFeat
662
709
case boILike:
663
710
if ( isNull ( vL ) || isNull ( vR ) )
664
711
return TVL_Unknown;
665
- else if ( isString ( vL ) && isString ( vR ) )
712
+ else
666
713
{
667
- QString str = qvString ( vL ), regexp = qvString ( vR );
714
+ QString str = getStringValue ( vL, parent ); ENSURE_NO_EVAL_ERROR;
715
+ QString regexp = getStringValue ( vR, parent ); ENSURE_NO_EVAL_ERROR;
668
716
// TODO: cache QRegExp in case that regexp is a literal string (i.e. it will stay constant)
669
717
bool matches;
670
718
if ( mOp == boLike || mOp == boILike ) // change from LIKE syntax to regexp
@@ -680,18 +728,16 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression* parent, QgsFeat
680
728
}
681
729
return matches ? TVL_True : TVL_False;
682
730
}
683
- else
684
- SET_EVAL_ERROR ( " Invalid arguments for regexp" );
685
731
686
732
case boConcat:
687
733
if ( isNull ( vL ) || isNull ( vR ) )
688
734
return QVariant ();
689
- else if ( isString ( vL ) || isString ( vR ) )
735
+ else
690
736
{
691
- return QVariant ( qvString ( vL ) + qvString ( vR ) );
737
+ QString sL = getStringValue ( vL, parent ); ENSURE_NO_EVAL_ERROR;
738
+ QString sR = getStringValue ( vR, parent ); ENSURE_NO_EVAL_ERROR;
739
+ return QVariant ( sL + sR );
692
740
}
693
- else
694
- SET_EVAL_ERROR ( " Invalid arguments for concatenation" );
695
741
696
742
default : break ;
697
743
}
@@ -775,12 +821,18 @@ QVariant QgsExpression::NodeInOperator::eval( QgsExpression* parent, QgsFeature*
775
821
{
776
822
bool equal = false ;
777
823
// check whether they are equal
778
- if ( isNumeric ( v1 ) && isNumeric ( v2 ) )
779
- equal = ( qvDouble ( v1 ) == qvDouble ( v2 ) );
780
- else if ( isString ( v1 ) && isString ( v2 ) )
781
- equal = ( QString::compare ( qvString ( v1 ), qvString ( v2 ) ) == 0 );
824
+ if ( isDoubleSafe ( v1 ) && isDoubleSafe ( v2 ) )
825
+ {
826
+ double f1 = getDoubleValue ( v1, parent ); ENSURE_NO_EVAL_ERROR;
827
+ double f2 = getDoubleValue ( v2, parent ); ENSURE_NO_EVAL_ERROR;
828
+ equal = f1 == f2;
829
+ }
782
830
else
783
- SET_EVAL_ERROR ( " Invalid arguments for comparison (IN operator)" );
831
+ {
832
+ QString s1 = getStringValue ( v1, parent ); ENSURE_NO_EVAL_ERROR;
833
+ QString s2 = getStringValue ( v2, parent ); ENSURE_NO_EVAL_ERROR;
834
+ equal = QString::compare ( s1, s2 ) == 0 ;
835
+ }
784
836
785
837
if ( equal ) // we know the result
786
838
return mNotIn ? TVL_False : TVL_True;
@@ -821,8 +873,11 @@ QVariant QgsExpression::NodeFunction::eval( QgsExpression* parent, QgsFeature* f
821
873
{
822
874
foreach ( Node* n, mArgs ->list () )
823
875
{
824
- argValues. append ( n->eval ( parent, f ) );
876
+ QVariant v = n->eval ( parent, f );
825
877
ENSURE_NO_EVAL_ERROR;
878
+ if ( isNull ( v ) )
879
+ return QVariant (); // all "normal" functions return NULL when any parameter is NULL
880
+ argValues.append ( v );
826
881
}
827
882
}
828
883
0 commit comments