QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsexpressionnodeimpl.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpressionnodeimpl.cpp
3  -------------------
4  begin : May 2017
5  copyright : (C) 2017 Matthias Kuhn
6  email : [email protected]
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsexpressionnodeimpl.h"
17 #include "qgsexpressionutils.h"
18 #include "qgsexpression.h"
19 
20 #include "qgsgeometry.h"
21 #include "qgsfeaturerequest.h"
22 
23 const char *QgsExpressionNodeBinaryOperator::BINARY_OPERATOR_TEXT[] =
24 {
25  // this must correspond (number and order of element) to the declaration of the enum BinaryOperator
26  "OR", "AND",
27  "=", "<>", "<=", ">=", "<", ">", "~", "LIKE", "NOT LIKE", "ILIKE", "NOT ILIKE", "IS", "IS NOT",
28  "+", "-", "*", "/", "//", "%", "^",
29  "||"
30 };
31 
32 const char *QgsExpressionNodeUnaryOperator::UNARY_OPERATOR_TEXT[] =
33 {
34  // this must correspond (number and order of element) to the declaration of the enum UnaryOperator
35  "NOT", "-"
36 };
37 
39 {
40  bool needs = false;
41  const QList< QgsExpressionNode * > nodeList = mList->list();
42  for ( QgsExpressionNode *n : nodeList )
43  needs |= n->needsGeometry();
44  return needs;
45 }
46 
48 {
49  qDeleteAll( mList );
50 }
51 
53 {
54  mList.append( node->node );
55  mNameList.append( cleanNamedNodeName( node->name ) );
56  mHasNamedNodes = true;
57  delete node;
58 }
59 
61 {
62  NodeList *nl = new NodeList;
63  for ( QgsExpressionNode *node : mList )
64  {
65  nl->mList.append( node->clone() );
66  }
67  nl->mNameList = mNameList;
68 
69  return nl;
70 }
71 
73 {
74  QString msg;
75  bool first = true;
76  for ( QgsExpressionNode *n : mList )
77  {
78  if ( !first ) msg += QLatin1String( ", " );
79  else first = false;
80  msg += n->dump();
81  }
82  return msg;
83 }
84 
85 QString QgsExpressionNode::NodeList::cleanNamedNodeName( const QString &name )
86 {
87  QString cleaned = name.toLower();
88 
89  // upgrade older argument names to standard versions
90  if ( cleaned == QLatin1String( "geom" ) )
91  cleaned = QStringLiteral( "geometry" );
92  else if ( cleaned == QLatin1String( "val" ) )
93  cleaned = QStringLiteral( "value" );
94  else if ( cleaned == QLatin1String( "geometry a" ) )
95  cleaned = QStringLiteral( "geometry1" );
96  else if ( cleaned == QLatin1String( "geometry b" ) )
97  cleaned = QStringLiteral( "geometry2" );
98 
99  return cleaned;
100 }
101 
102 
103 //
104 
106 {
107  QVariant val = mOperand->eval( parent, context );
109 
110  switch ( mOp )
111  {
112  case uoNot:
113  {
114  QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( val, parent );
116  return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::NOT[tvl] );
117  }
118 
119  case uoMinus:
120  if ( QgsExpressionUtils::isIntSafe( val ) )
121  return QVariant( - QgsExpressionUtils::getIntValue( val, parent ) );
122  else if ( QgsExpressionUtils::isDoubleSafe( val ) )
123  return QVariant( - QgsExpressionUtils::getDoubleValue( val, parent ) );
124  else
125  SET_EVAL_ERROR( tr( "Unary minus only for numeric values." ) );
126  default:
127  Q_ASSERT( false && "unknown unary operation" );
128  }
129  return QVariant();
130 }
131 
133 {
134  return ntUnaryOperator;
135 }
136 
138 {
139  return mOperand->prepare( parent, context );
140 }
141 
143 {
144  if ( dynamic_cast<QgsExpressionNodeBinaryOperator *>( mOperand ) )
145  return QStringLiteral( "%1 ( %2 )" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
146  else
147  return QStringLiteral( "%1 %2" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
148 }
149 
151 {
152  return mOperand->referencedColumns();
153 }
154 
156 {
157  return mOperand->referencedVariables();
158 }
159 
161 {
162  return mOperand->referencedFunctions();
163 }
164 
165 QList<const QgsExpressionNode *> QgsExpressionNodeUnaryOperator::nodes() const
166 {
167  QList<const QgsExpressionNode *> lst;
168  lst.append( this );
169  lst += mOperand->nodes();
170  return lst;
171 }
172 
174 {
175  return mOperand->needsGeometry();
176 }
177 
179 {
180  QgsExpressionNodeUnaryOperator *copy = new QgsExpressionNodeUnaryOperator( mOp, mOperand->clone() );
181  cloneTo( copy );
182  return copy;
183 }
184 
186 {
187  return mOperand->isStatic( parent, context );
188 }
189 
191 {
192  return UNARY_OPERATOR_TEXT[mOp];
193 }
194 
195 //
196 
198 {
199  QVariant vL = mOpLeft->eval( parent, context );
201 
202  if ( mOp == boAnd || mOp == boOr )
203  {
204  QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent );
206  if ( mOp == boAnd && tvlL == QgsExpressionUtils::False )
207  return TVL_False; // shortcut -- no need to evaluate right-hand side
208  if ( mOp == boOr && tvlL == QgsExpressionUtils::True )
209  return TVL_True; // shortcut -- no need to evaluate right-hand side
210  }
211 
212  QVariant vR = mOpRight->eval( parent, context );
214 
215  switch ( mOp )
216  {
217  case boPlus:
218  if ( vL.type() == QVariant::String && vR.type() == QVariant::String )
219  {
220  QString sL = QgsExpressionUtils::isNull( vL ) ? QString() : QgsExpressionUtils::getStringValue( vL, parent );
222  QString sR = QgsExpressionUtils::isNull( vR ) ? QString() : QgsExpressionUtils::getStringValue( vR, parent );
224  return QVariant( sL + sR );
225  }
226  //intentional fall-through
228  case boMinus:
229  case boMul:
230  case boDiv:
231  case boMod:
232  {
233  if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
234  return QVariant();
235  else if ( mOp != boDiv && QgsExpressionUtils::isIntSafe( vL ) && QgsExpressionUtils::isIntSafe( vR ) )
236  {
237  // both are integers - let's use integer arithmetic
238  qlonglong iL = QgsExpressionUtils::getIntValue( vL, parent );
240  qlonglong iR = QgsExpressionUtils::getIntValue( vR, parent );
242 
243  if ( mOp == boMod && iR == 0 )
244  return QVariant();
245 
246  return QVariant( computeInt( iL, iR ) );
247  }
248  else if ( QgsExpressionUtils::isDateTimeSafe( vL ) && QgsExpressionUtils::isIntervalSafe( vR ) )
249  {
250  QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
252  QgsInterval iL = QgsExpressionUtils::getInterval( vR, parent );
254  if ( mOp == boDiv || mOp == boMul || mOp == boMod )
255  {
256  parent->setEvalErrorString( tr( "Can't perform /, *, or % on DateTime and Interval" ) );
257  return QVariant();
258  }
259  return QVariant( computeDateTimeFromInterval( dL, &iL ) );
260  }
261  else if ( mOp == boPlus && ( ( vL.type() == QVariant::Date && vR.type() == QVariant::Time ) ||
262  ( vR.type() == QVariant::Date && vL.type() == QVariant::Time ) ) )
263  {
264  QDate date = QgsExpressionUtils::getDateValue( vL.type() == QVariant::Date ? vL : vR, parent );
266  QTime time = QgsExpressionUtils::getTimeValue( vR.type() == QVariant::Time ? vR : vL, parent );
268  QDateTime dt = QDateTime( date, time );
269  return QVariant( dt );
270  }
271  else if ( mOp == boMinus && vL.type() == QVariant::Date && vR.type() == QVariant::Date )
272  {
273  QDate date1 = QgsExpressionUtils::getDateValue( vL, parent );
275  QDate date2 = QgsExpressionUtils::getDateValue( vR, parent );
277  return date1 - date2;
278  }
279  else if ( mOp == boMinus && vL.type() == QVariant::Time && vR.type() == QVariant::Time )
280  {
281  QTime time1 = QgsExpressionUtils::getTimeValue( vL, parent );
283  QTime time2 = QgsExpressionUtils::getTimeValue( vR, parent );
285  return time1 - time2;
286  }
287  else if ( mOp == boMinus && vL.type() == QVariant::DateTime && vR.type() == QVariant::DateTime )
288  {
289  QDateTime datetime1 = QgsExpressionUtils::getDateTimeValue( vL, parent );
291  QDateTime datetime2 = QgsExpressionUtils::getDateTimeValue( vR, parent );
293  return datetime1 - datetime2;
294  }
295  else
296  {
297  // general floating point arithmetic
298  double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
300  double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
302  if ( ( mOp == boDiv || mOp == boMod ) && fR == 0. )
303  return QVariant(); // silently handle division by zero and return NULL
304  return QVariant( computeDouble( fL, fR ) );
305  }
306  }
307  case boIntDiv:
308  {
309  //integer division
310  double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
312  double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
314  if ( fR == 0. )
315  return QVariant(); // silently handle division by zero and return NULL
316  return QVariant( qlonglong( std::floor( fL / fR ) ) );
317  }
318  case boPow:
319  if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
320  return QVariant();
321  else
322  {
323  double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
325  double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
327  return QVariant( std::pow( fL, fR ) );
328  }
329 
330  case boAnd:
331  {
332  QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
334  return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::AND[tvlL][tvlR] );
335  }
336 
337  case boOr:
338  {
339  QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
341  return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::OR[tvlL][tvlR] );
342  }
343 
344  case boEQ:
345  case boNE:
346  case boLT:
347  case boGT:
348  case boLE:
349  case boGE:
350  if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
351  {
352  return TVL_Unknown;
353  }
354  else if ( QgsExpressionUtils::isList( vL ) || QgsExpressionUtils::isList( vR ) )
355  {
356  // verify that we have two lists
357  if ( !QgsExpressionUtils::isList( vL ) || !QgsExpressionUtils::isList( vR ) )
358  return TVL_Unknown;
359 
360  // and search for not equal respective items
361  QVariantList lL = vL.toList();
362  QVariantList lR = vR.toList();
363  for ( int i = 0; i < lL.length() && i < lR.length(); i++ )
364  {
365  if ( QgsExpressionUtils::isNull( lL.at( i ) ) && QgsExpressionUtils::isNull( lR.at( i ) ) )
366  continue; // same behavior as PostgreSQL
367 
368  if ( QgsExpressionUtils::isNull( lL.at( i ) ) || QgsExpressionUtils::isNull( lR.at( i ) ) )
369  {
370  switch ( mOp )
371  {
372  case boEQ:
373  return false;
374  case boNE:
375  return true;
376  case boLT:
377  case boLE:
378  return QgsExpressionUtils::isNull( lR.at( i ) );
379  case boGT:
380  case boGE:
381  return QgsExpressionUtils::isNull( lL.at( i ) );
382  default:
383  Q_ASSERT( false );
384  return TVL_Unknown;
385  }
386  }
387 
388  QgsExpressionNodeLiteral nL( lL.at( i ) );
389  QgsExpressionNodeLiteral nR( lR.at( i ) );
390  QgsExpressionNodeBinaryOperator eqNode( boEQ, nL.clone(), nR.clone() );
391  QVariant eq = eqNode.eval( parent, context );
393  if ( eq == TVL_False )
394  {
395  // return the two items comparison
396  QgsExpressionNodeBinaryOperator node( mOp, nL.clone(), nR.clone() );
397  QVariant v = node.eval( parent, context );
399  return v;
400  }
401  }
402 
403  // default to length comparison
404  switch ( mOp )
405  {
406  case boEQ:
407  return lL.length() == lR.length();
408  case boNE:
409  return lL.length() != lR.length();
410  case boLT:
411  return lL.length() < lR.length();
412  case boGT:
413  return lL.length() > lR.length();
414  case boLE:
415  return lL.length() <= lR.length();
416  case boGE:
417  return lL.length() >= lR.length();
418  default:
419  Q_ASSERT( false );
420  return TVL_Unknown;
421  }
422  }
423  else if ( ( vL.type() == QVariant::DateTime && vR.type() == QVariant::DateTime ) )
424  {
425  QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
427  QDateTime dR = QgsExpressionUtils::getDateTimeValue( vR, parent );
429 
430  // while QDateTime has innate handling of timezones, we don't expose these ANYWHERE
431  // in QGIS. So to avoid confusion where seemingly equal datetime values give unexpected
432  // results (due to different hidden timezones), we force all datetime comparisons to treat
433  // all datetime values as having the same time zone
434  dL.setTimeSpec( Qt::UTC );
435  dR.setTimeSpec( Qt::UTC );
436 
437  return compare( dR.msecsTo( dL ) ) ? TVL_True : TVL_False;
438  }
439  else if ( ( vL.type() == QVariant::Date && vR.type() == QVariant::Date ) )
440  {
441  const QDate dL = QgsExpressionUtils::getDateValue( vL, parent );
443  const QDate dR = QgsExpressionUtils::getDateValue( vR, parent );
445  return compare( dR.daysTo( dL ) ) ? TVL_True : TVL_False;
446  }
447  else if ( ( vL.type() == QVariant::Time && vR.type() == QVariant::Time ) )
448  {
449  const QTime dL = QgsExpressionUtils::getTimeValue( vL, parent );
451  const QTime dR = QgsExpressionUtils::getTimeValue( vR, parent );
453  return compare( dR.msecsTo( dL ) ) ? TVL_True : TVL_False;
454  }
455  else if ( ( vL.type() != QVariant::String || vR.type() != QVariant::String ) &&
456  QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) )
457  {
458  // do numeric comparison if both operators can be converted to numbers,
459  // and they aren't both string
460  double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
462  double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
464  return compare( fL - fR ) ? TVL_True : TVL_False;
465  }
466  // warning - QgsExpression::isIntervalSafe is VERY expensive and should not be used here
467  else if ( vL.canConvert< QgsInterval >() && vR.canConvert< QgsInterval >() )
468  {
469  double fL = QgsExpressionUtils::getInterval( vL, parent ).seconds();
471  double fR = QgsExpressionUtils::getInterval( vR, parent ).seconds();
473  return compare( fL - fR ) ? TVL_True : TVL_False;
474  }
475  else
476  {
477  // do string comparison otherwise
478  QString sL = QgsExpressionUtils::getStringValue( vL, parent );
480  QString sR = QgsExpressionUtils::getStringValue( vR, parent );
482  int diff = QString::compare( sL, sR );
483  return compare( diff ) ? TVL_True : TVL_False;
484  }
485 
486  case boIs:
487  case boIsNot:
488  if ( QgsExpressionUtils::isNull( vL ) && QgsExpressionUtils::isNull( vR ) ) // both operators null
489  return ( mOp == boIs ? TVL_True : TVL_False );
490  else if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) ) // one operator null
491  return ( mOp == boIs ? TVL_False : TVL_True );
492  else // both operators non-null
493  {
494  bool equal = false;
495  if ( QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) &&
496  ( vL.type() != QVariant::String || vR.type() != QVariant::String ) )
497  {
498  double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
500  double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
502  equal = qgsDoubleNear( fL, fR );
503  }
504  else
505  {
506  QString sL = QgsExpressionUtils::getStringValue( vL, parent );
508  QString sR = QgsExpressionUtils::getStringValue( vR, parent );
510  equal = QString::compare( sL, sR ) == 0;
511  }
512  if ( equal )
513  return mOp == boIs ? TVL_True : TVL_False;
514  else
515  return mOp == boIs ? TVL_False : TVL_True;
516  }
517 
518  case boRegexp:
519  case boLike:
520  case boNotLike:
521  case boILike:
522  case boNotILike:
523  if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
524  return TVL_Unknown;
525  else
526  {
527  QString str = QgsExpressionUtils::getStringValue( vL, parent );
529  QString regexp = QgsExpressionUtils::getStringValue( vR, parent );
531  // TODO: cache QRegExp in case that regexp is a literal string (i.e. it will stay constant)
532  bool matches;
533  if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike ) // change from LIKE syntax to regexp
534  {
535  QString esc_regexp = QRegExp::escape( regexp );
536  // manage escape % and _
537  if ( esc_regexp.startsWith( '%' ) )
538  {
539  esc_regexp.replace( 0, 1, QStringLiteral( ".*" ) );
540  }
541  QRegExp rx( "[^\\\\](%)" );
542  int pos = 0;
543  while ( ( pos = rx.indexIn( esc_regexp, pos ) ) != -1 )
544  {
545  esc_regexp.replace( pos + 1, 1, QStringLiteral( ".*" ) );
546  pos += 1;
547  }
548  rx.setPattern( QStringLiteral( "\\\\%" ) );
549  esc_regexp.replace( rx, QStringLiteral( "%" ) );
550  if ( esc_regexp.startsWith( '_' ) )
551  {
552  esc_regexp.replace( 0, 1, QStringLiteral( "." ) );
553  }
554  rx.setPattern( QStringLiteral( "[^\\\\](_)" ) );
555  pos = 0;
556  while ( ( pos = rx.indexIn( esc_regexp, pos ) ) != -1 )
557  {
558  esc_regexp.replace( pos + 1, 1, '.' );
559  pos += 1;
560  }
561  rx.setPattern( QStringLiteral( "\\\\_" ) );
562  esc_regexp.replace( rx, QStringLiteral( "_" ) );
563  matches = QRegExp( esc_regexp, mOp == boLike || mOp == boNotLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
564  }
565  else
566  {
567  matches = QRegExp( regexp ).indexIn( str ) != -1;
568  }
569 
570  if ( mOp == boNotLike || mOp == boNotILike )
571  {
572  matches = !matches;
573  }
574 
575  return matches ? TVL_True : TVL_False;
576  }
577 
578  case boConcat:
579  if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
580  return QVariant();
581  else
582  {
583  QString sL = QgsExpressionUtils::getStringValue( vL, parent );
585  QString sR = QgsExpressionUtils::getStringValue( vR, parent );
587  return QVariant( sL + sR );
588  }
589 
590  default:
591  break;
592  }
593  Q_ASSERT( false );
594  return QVariant();
595 }
596 
597 bool QgsExpressionNodeBinaryOperator::compare( double diff )
598 {
599  switch ( mOp )
600  {
601  case boEQ:
602  return qgsDoubleNear( diff, 0.0 );
603  case boNE:
604  return !qgsDoubleNear( diff, 0.0 );
605  case boLT:
606  return diff < 0;
607  case boGT:
608  return diff > 0;
609  case boLE:
610  return diff <= 0;
611  case boGE:
612  return diff >= 0;
613  default:
614  Q_ASSERT( false );
615  return false;
616  }
617 }
618 
619 qlonglong QgsExpressionNodeBinaryOperator::computeInt( qlonglong x, qlonglong y )
620 {
621  switch ( mOp )
622  {
623  case boPlus:
624  return x + y;
625  case boMinus:
626  return x - y;
627  case boMul:
628  return x * y;
629  case boDiv:
630  return x / y;
631  case boMod:
632  return x % y;
633  default:
634  Q_ASSERT( false );
635  return 0;
636  }
637 }
638 
639 QDateTime QgsExpressionNodeBinaryOperator::computeDateTimeFromInterval( const QDateTime &d, QgsInterval *i )
640 {
641  switch ( mOp )
642  {
643  case boPlus:
644  return d.addSecs( i->seconds() );
645  case boMinus:
646  return d.addSecs( -i->seconds() );
647  default:
648  Q_ASSERT( false );
649  return QDateTime();
650  }
651 }
652 
653 double QgsExpressionNodeBinaryOperator::computeDouble( double x, double y )
654 {
655  switch ( mOp )
656  {
657  case boPlus:
658  return x + y;
659  case boMinus:
660  return x - y;
661  case boMul:
662  return x * y;
663  case boDiv:
664  return x / y;
665  case boMod:
666  return std::fmod( x, y );
667  default:
668  Q_ASSERT( false );
669  return 0;
670  }
671 }
672 
674 {
675  return ntBinaryOperator;
676 }
677 
679 {
680  bool resL = mOpLeft->prepare( parent, context );
681  bool resR = mOpRight->prepare( parent, context );
682  return resL && resR;
683 }
684 
686 {
687  // see left/right in qgsexpressionparser.yy
688  switch ( mOp )
689  {
690  case boOr:
691  return 1;
692 
693  case boAnd:
694  return 2;
695 
696  case boEQ:
697  case boNE:
698  case boLE:
699  case boGE:
700  case boLT:
701  case boGT:
702  case boRegexp:
703  case boLike:
704  case boILike:
705  case boNotLike:
706  case boNotILike:
707  case boIs:
708  case boIsNot:
709  return 3;
710 
711  case boPlus:
712  case boMinus:
713  return 4;
714 
715  case boMul:
716  case boDiv:
717  case boIntDiv:
718  case boMod:
719  return 5;
720 
721  case boPow:
722  return 6;
723 
724  case boConcat:
725  return 7;
726  }
727  Q_ASSERT( false && "unexpected binary operator" );
728  return -1;
729 }
730 
732 {
733  // see left/right in qgsexpressionparser.yy
734  switch ( mOp )
735  {
736  case boOr:
737  case boAnd:
738  case boEQ:
739  case boNE:
740  case boLE:
741  case boGE:
742  case boLT:
743  case boGT:
744  case boRegexp:
745  case boLike:
746  case boILike:
747  case boNotLike:
748  case boNotILike:
749  case boIs:
750  case boIsNot:
751  case boPlus:
752  case boMinus:
753  case boMul:
754  case boDiv:
755  case boIntDiv:
756  case boMod:
757  case boConcat:
758  return true;
759 
760  case boPow:
761  return false;
762  }
763  Q_ASSERT( false && "unexpected binary operator" );
764  return false;
765 }
766 
768 {
769  QgsExpressionNodeBinaryOperator *lOp = dynamic_cast<QgsExpressionNodeBinaryOperator *>( mOpLeft );
770  QgsExpressionNodeBinaryOperator *rOp = dynamic_cast<QgsExpressionNodeBinaryOperator *>( mOpRight );
771  QgsExpressionNodeUnaryOperator *ruOp = dynamic_cast<QgsExpressionNodeUnaryOperator *>( mOpRight );
772 
773  QString rdump( mOpRight->dump() );
774 
775  // avoid dumping "IS (NOT ...)" as "IS NOT ..."
776  if ( mOp == boIs && ruOp && ruOp->op() == QgsExpressionNodeUnaryOperator::uoNot )
777  {
778  rdump.prepend( '(' ).append( ')' );
779  }
780 
781  QString fmt;
782  if ( leftAssociative() )
783  {
784  fmt += lOp && ( lOp->precedence() < precedence() ) ? QStringLiteral( "(%1)" ) : QStringLiteral( "%1" );
785  fmt += QLatin1String( " %2 " );
786  fmt += rOp && ( rOp->precedence() <= precedence() ) ? QStringLiteral( "(%3)" ) : QStringLiteral( "%3" );
787  }
788  else
789  {
790  fmt += lOp && ( lOp->precedence() <= precedence() ) ? QStringLiteral( "(%1)" ) : QStringLiteral( "%1" );
791  fmt += QLatin1String( " %2 " );
792  fmt += rOp && ( rOp->precedence() < precedence() ) ? QStringLiteral( "(%3)" ) : QStringLiteral( "%3" );
793  }
794 
795  return fmt.arg( mOpLeft->dump(), BINARY_OPERATOR_TEXT[mOp], rdump );
796 }
797 
799 {
800  return mOpLeft->referencedColumns() + mOpRight->referencedColumns();
801 }
802 
804 {
805  return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
806 }
807 
809 {
810  return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
811 }
812 
813 QList<const QgsExpressionNode *> QgsExpressionNodeBinaryOperator::nodes() const
814 {
815  QList<const QgsExpressionNode *> lst;
816  lst << this;
817  lst += mOpLeft->nodes() + mOpRight->nodes();
818  return lst;
819 }
820 
822 {
823  return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
824 }
825 
827 {
828  QgsExpressionNodeBinaryOperator *copy = new QgsExpressionNodeBinaryOperator( mOp, mOpLeft->clone(), mOpRight->clone() );
829  cloneTo( copy );
830  return copy;
831 }
832 
834 {
835  return mOpLeft->isStatic( parent, context ) && mOpRight->isStatic( parent, context );
836 }
837 
838 //
839 
841 {
842  if ( mList->count() == 0 )
843  return mNotIn ? TVL_True : TVL_False;
844  QVariant v1 = mNode->eval( parent, context );
846  if ( QgsExpressionUtils::isNull( v1 ) )
847  return TVL_Unknown;
848 
849  bool listHasNull = false;
850 
851  const QList< QgsExpressionNode * > nodeList = mList->list();
852  for ( QgsExpressionNode *n : nodeList )
853  {
854  QVariant v2 = n->eval( parent, context );
856  if ( QgsExpressionUtils::isNull( v2 ) )
857  listHasNull = true;
858  else
859  {
860  bool equal = false;
861  // check whether they are equal
862  if ( ( v1.type() != QVariant::String || v2.type() != QVariant::String ) &&
863  QgsExpressionUtils::isDoubleSafe( v1 ) && QgsExpressionUtils::isDoubleSafe( v2 ) )
864  {
865  // do numeric comparison if both operators can be converted to numbers,
866  // and they aren't both string
867  double f1 = QgsExpressionUtils::getDoubleValue( v1, parent );
869  double f2 = QgsExpressionUtils::getDoubleValue( v2, parent );
871  equal = qgsDoubleNear( f1, f2 );
872  }
873  else
874  {
875  QString s1 = QgsExpressionUtils::getStringValue( v1, parent );
877  QString s2 = QgsExpressionUtils::getStringValue( v2, parent );
879  equal = QString::compare( s1, s2 ) == 0;
880  }
881 
882  if ( equal ) // we know the result
883  return mNotIn ? TVL_False : TVL_True;
884  }
885  }
886 
887  // item not found
888  if ( listHasNull )
889  return TVL_Unknown;
890  else
891  return mNotIn ? TVL_True : TVL_False;
892 }
893 
895 {
896  delete mNode;
897  delete mList;
898 }
899 
901 {
902  return ntInOperator;
903 }
904 
906 {
907  bool res = mNode->prepare( parent, context );
908  const QList< QgsExpressionNode * > nodeList = mList->list();
909  for ( QgsExpressionNode *n : nodeList )
910  {
911  res = res && n->prepare( parent, context );
912  }
913  return res;
914 }
915 
917 {
918  return QStringLiteral( "%1 %2 IN (%3)" ).arg( mNode->dump(), mNotIn ? "NOT" : "", mList->dump() );
919 }
920 
922 {
923  QgsExpressionNodeInOperator *copy = new QgsExpressionNodeInOperator( mNode->clone(), mList->clone(), mNotIn );
924  cloneTo( copy );
925  return copy;
926 }
927 
929 {
930  if ( !mNode->isStatic( parent, context ) )
931  return false;
932 
933  const QList< QgsExpressionNode * > nodeList = mList->list();
934  for ( QgsExpressionNode *n : nodeList )
935  {
936  if ( !n->isStatic( parent, context ) )
937  return false;
938  }
939 
940  return true;
941 }
942 
943 //
944 
946 {
947  QString name = QgsExpression::QgsExpression::Functions()[mFnIndex]->name();
948  QgsExpressionFunction *fd = context && context->hasFunction( name ) ? context->function( name ) : QgsExpression::QgsExpression::Functions()[mFnIndex];
949 
950  QVariant res = fd->run( mArgs, context, parent, this );
952 
953  // everything went fine
954  return res;
955 }
956 
958  : mFnIndex( fnIndex )
959 {
960  const QgsExpressionFunction::ParameterList &functionParams = QgsExpression::QgsExpression::Functions()[mFnIndex]->parameters();
961  if ( !args || functionParams.isEmpty() )
962  {
963  // no QgsExpressionFunction::Parameters, or function does not support them
964  mArgs = args;
965  }
966  else
967  {
968  mArgs = new NodeList();
969 
970  int idx = 0;
971  //first loop through unnamed arguments
972  while ( idx < args->names().size() && args->names().at( idx ).isEmpty() )
973  {
974  mArgs->append( args->list().at( idx )->clone() );
975  idx++;
976  }
977 
978  //next copy named QgsExpressionFunction::Parameters in order expected by function
979  for ( ; idx < functionParams.count(); ++idx )
980  {
981  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
982  if ( nodeIdx < 0 )
983  {
984  //QgsExpressionFunction::Parameter not found - insert default value for QgsExpressionFunction::Parameter
985  mArgs->append( new QgsExpressionNodeLiteral( functionParams.at( idx ).defaultValue() ) );
986  }
987  else
988  {
989  mArgs->append( args->list().at( nodeIdx )->clone() );
990  }
991  }
992 
993  delete args;
994  }
995 }
996 
998 {
999  delete mArgs;
1000 }
1001 
1003 {
1004  return ntFunction;
1005 }
1006 
1008 {
1009  QgsExpressionFunction *fd = QgsExpression::QgsExpression::Functions()[mFnIndex];
1010 
1011  bool res = fd->prepare( this, parent, context );
1012  if ( mArgs && !fd->lazyEval() )
1013  {
1014  const QList< QgsExpressionNode * > nodeList = mArgs->list();
1015  for ( QgsExpressionNode *n : nodeList )
1016  {
1017  res = res && n->prepare( parent, context );
1018  }
1019  }
1020  return res;
1021 }
1022 
1024 {
1025  QgsExpressionFunction *fd = QgsExpression::QgsExpression::Functions()[mFnIndex];
1026  if ( fd->params() == 0 )
1027  return QStringLiteral( "%1%2" ).arg( fd->name(), fd->name().startsWith( '$' ) ? QString() : QStringLiteral( "()" ) ); // special column
1028  else
1029  return QStringLiteral( "%1(%2)" ).arg( fd->name(), mArgs ? mArgs->dump() : QString() ); // function
1030 }
1031 
1033 {
1034  QgsExpressionFunction *fd = QgsExpression::QgsExpression::Functions()[mFnIndex];
1035  QSet<QString> functionColumns = fd->referencedColumns( this );
1036 
1037  if ( !mArgs )
1038  {
1039  //no referenced columns in arguments, just return function's referenced columns
1040  return functionColumns;
1041  }
1042 
1043  int paramIndex = 0;
1044  const QList< QgsExpressionNode * > nodeList = mArgs->list();
1045  for ( QgsExpressionNode *n : nodeList )
1046  {
1047  if ( fd->parameters().count() <= paramIndex || !fd->parameters().at( paramIndex ).isSubExpression() )
1048  functionColumns.unite( n->referencedColumns() );
1049  paramIndex++;
1050  }
1051 
1052  return functionColumns;
1053 }
1054 
1056 {
1057  QgsExpressionFunction *fd = QgsExpression::QgsExpression::Functions()[mFnIndex];
1058  if ( fd->name() == QLatin1String( "var" ) )
1059  {
1060  if ( !mArgs->list().isEmpty() )
1061  {
1062  QgsExpressionNodeLiteral *var = dynamic_cast<QgsExpressionNodeLiteral *>( mArgs->list().at( 0 ) );
1063  if ( var )
1064  return QSet<QString>() << var->value().toString();
1065  }
1066  return QSet<QString>() << QString();
1067  }
1068  else
1069  {
1070  QSet<QString> functionVariables = QSet<QString>();
1071 
1072  if ( !mArgs )
1073  return functionVariables;
1074 
1075  const QList< QgsExpressionNode * > nodeList = mArgs->list();
1076  for ( QgsExpressionNode *n : nodeList )
1077  {
1078  functionVariables.unite( n->referencedVariables() );
1079  }
1080 
1081  return functionVariables;
1082  }
1083 }
1084 
1086 {
1087  QgsExpressionFunction *fd = QgsExpression::QgsExpression::Functions()[mFnIndex];
1088  QSet<QString> functions = QSet<QString>();
1089  functions.insert( fd->name() );
1090 
1091  if ( !mArgs )
1092  return functions;
1093 
1094  const QList< QgsExpressionNode * > nodeList = mArgs->list();
1095  for ( QgsExpressionNode *n : nodeList )
1096  {
1097  functions.unite( n->referencedFunctions() );
1098  }
1099  return functions;
1100 }
1101 
1102 QList<const QgsExpressionNode *> QgsExpressionNodeFunction::nodes() const
1103 {
1104  QList<const QgsExpressionNode *> lst;
1105  lst << this;
1106  if ( !mArgs )
1107  return lst;
1108 
1109  const QList< QgsExpressionNode * > nodeList = mArgs->list();
1110  for ( QgsExpressionNode *n : nodeList )
1111  {
1112  lst += n->nodes();
1113  }
1114  return lst;
1115 }
1116 
1118 {
1119  bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry( this );
1120  if ( mArgs )
1121  {
1122  const QList< QgsExpressionNode * > nodeList = mArgs->list();
1123  for ( QgsExpressionNode *n : nodeList )
1124  needs |= n->needsGeometry();
1125  }
1126  return needs;
1127 }
1128 
1130 {
1131  QgsExpressionNodeFunction *copy = new QgsExpressionNodeFunction( mFnIndex, mArgs ? mArgs->clone() : nullptr );
1132  cloneTo( copy );
1133  return copy;
1134 }
1135 
1137 {
1138  return QgsExpression::Functions()[mFnIndex]->isStatic( this, parent, context );
1139 }
1140 
1142 {
1143  if ( !args || !args->hasNamedNodes() )
1144  return true;
1145 
1146  const QgsExpressionFunction::ParameterList &functionParams = QgsExpression::Functions()[fnIndex]->parameters();
1147  if ( functionParams.isEmpty() )
1148  {
1149  error = QStringLiteral( "%1 does not support named QgsExpressionFunction::Parameters" ).arg( QgsExpression::Functions()[fnIndex]->name() );
1150  return false;
1151  }
1152  else
1153  {
1154  QSet< int > providedArgs;
1155  QSet< int > handledArgs;
1156  int idx = 0;
1157  //first loop through unnamed arguments
1158  while ( args->names().at( idx ).isEmpty() )
1159  {
1160  providedArgs << idx;
1161  handledArgs << idx;
1162  idx++;
1163  }
1164 
1165  //next check named QgsExpressionFunction::Parameters
1166  for ( ; idx < functionParams.count(); ++idx )
1167  {
1168  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1169  if ( nodeIdx < 0 )
1170  {
1171  if ( !functionParams.at( idx ).optional() )
1172  {
1173  error = QStringLiteral( "No value specified for QgsExpressionFunction::Parameter '%1' for %2" ).arg( functionParams.at( idx ).name(), QgsExpression::Functions()[fnIndex]->name() );
1174  return false;
1175  }
1176  }
1177  else
1178  {
1179  if ( providedArgs.contains( idx ) )
1180  {
1181  error = QStringLiteral( "Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(), QgsExpression::Functions()[fnIndex]->name() );
1182  return false;
1183  }
1184  }
1185  providedArgs << idx;
1186  handledArgs << nodeIdx;
1187  }
1188 
1189  //last check for bad names
1190  idx = 0;
1191  const QStringList nameList = args->names();
1192  for ( const QString &name : nameList )
1193  {
1194  if ( !name.isEmpty() && !functionParams.contains( name ) )
1195  {
1196  error = QStringLiteral( "Invalid QgsExpressionFunction::Parameter name '%1' for %2" ).arg( name, QgsExpression::Functions()[fnIndex]->name() );
1197  return false;
1198  }
1199  if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1200  {
1201  int functionIdx = functionParams.indexOf( name );
1202  if ( providedArgs.contains( functionIdx ) )
1203  {
1204  error = QStringLiteral( "Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(), QgsExpression::Functions()[fnIndex]->name() );
1205  return false;
1206  }
1207  }
1208  idx++;
1209  }
1210 
1211  }
1212  return true;
1213 }
1214 
1215 //
1216 
1218 {
1219  Q_UNUSED( context )
1220  Q_UNUSED( parent )
1221  return mValue;
1222 }
1223 
1225 {
1226  return ntLiteral;
1227 }
1228 
1230 {
1231  Q_UNUSED( parent )
1232  Q_UNUSED( context )
1233  return true;
1234 }
1235 
1236 
1238 {
1239  if ( mValue.isNull() )
1240  return QStringLiteral( "NULL" );
1241 
1242  switch ( mValue.type() )
1243  {
1244  case QVariant::Int:
1245  return QString::number( mValue.toInt() );
1246  case QVariant::Double:
1247  return QString::number( mValue.toDouble() );
1248  case QVariant::LongLong:
1249  return QString::number( mValue.toLongLong() );
1250  case QVariant::String:
1251  return QgsExpression::quotedString( mValue.toString() );
1252  case QVariant::Bool:
1253  return mValue.toBool() ? QStringLiteral( "TRUE" ) : QStringLiteral( "FALSE" );
1254  default:
1255  return tr( "[unsupported type: %1; value: %2]" ).arg( mValue.typeName(), mValue.toString() );
1256  }
1257 }
1258 
1260 {
1261  return QSet<QString>();
1262 }
1263 
1265 {
1266  return QSet<QString>();
1267 }
1268 
1270 {
1271  return QSet<QString>();
1272 }
1273 
1274 QList<const QgsExpressionNode *> QgsExpressionNodeLiteral::nodes() const
1275 {
1276  QList<const QgsExpressionNode *> lst;
1277  lst << this;
1278  return lst;
1279 }
1280 
1282 {
1283  return false;
1284 }
1285 
1287 {
1288  QgsExpressionNodeLiteral *copy = new QgsExpressionNodeLiteral( mValue );
1289  cloneTo( copy );
1290  return copy;
1291 }
1292 
1294 {
1295  Q_UNUSED( context )
1296  Q_UNUSED( parent )
1297  return true;
1298 }
1299 
1300 //
1301 
1303 {
1304  Q_UNUSED( parent )
1305  int index = mIndex;
1306 
1307  if ( index < 0 )
1308  {
1309  // have not yet found field index - first check explicitly set fields collection
1310  if ( context && context->hasVariable( QgsExpressionContext::EXPR_FIELDS ) )
1311  {
1312  QgsFields fields = qvariant_cast<QgsFields>( context->variable( QgsExpressionContext::EXPR_FIELDS ) );
1313  index = fields.lookupField( mName );
1314  }
1315  }
1316 
1317  if ( context )
1318  {
1319  QgsFeature feature = context->feature();
1320  if ( feature.isValid() )
1321  {
1322  if ( index >= 0 )
1323  return feature.attribute( index );
1324  else
1325  return feature.attribute( mName );
1326  }
1327  else
1328  {
1329  parent->setEvalErrorString( tr( "No feature available for field '%1' evaluation" ).arg( mName ) );
1330  }
1331  }
1332  if ( index < 0 )
1333  parent->setEvalErrorString( tr( "Field '%1' not found" ).arg( mName ) );
1334  return QVariant();
1335 }
1336 
1338 {
1339  return ntColumnRef;
1340 }
1341 
1343 {
1344  if ( !context || !context->hasVariable( QgsExpressionContext::EXPR_FIELDS ) )
1345  return false;
1346 
1347  QgsFields fields = qvariant_cast<QgsFields>( context->variable( QgsExpressionContext::EXPR_FIELDS ) );
1348 
1349  mIndex = fields.lookupField( mName );
1350 
1351  if ( mIndex == -1 && context->hasFeature() )
1352  {
1353  mIndex = context->feature().fieldNameIndex( mName );
1354  }
1355 
1356  if ( mIndex == -1 )
1357  {
1358  parent->setEvalErrorString( tr( "Field '%1' not found" ).arg( mName ) );
1359  return false;
1360  }
1361  return true;
1362 }
1363 
1365 {
1366  return QRegExp( "^[A-Za-z_\x80-\xff][A-Za-z0-9_\x80-\xff]*$" ).exactMatch( mName ) ? mName : QgsExpression::quotedColumnRef( mName );
1367 }
1368 
1370 {
1371  return QSet<QString>() << mName;
1372 }
1373 
1375 {
1376  return QSet<QString>();
1377 }
1378 
1380 {
1381  return QSet<QString>();
1382 }
1383 
1384 QList<const QgsExpressionNode *> QgsExpressionNodeColumnRef::nodes() const
1385 {
1386  QList<const QgsExpressionNode *> result;
1387  result << this;
1388  return result;
1389 }
1390 
1392 {
1393  return false;
1394 }
1395 
1397 {
1399  cloneTo( copy );
1400  return copy;
1401 }
1402 
1404 {
1405  Q_UNUSED( context )
1406  Q_UNUSED( parent )
1407  return false;
1408 }
1409 
1410 //
1411 
1413  : mConditions( *conditions )
1414  , mElseExp( elseExp )
1415 {
1416  delete conditions;
1417 }
1418 
1420 {
1421  delete mElseExp;
1422  qDeleteAll( mConditions );
1423 }
1424 
1426 {
1427  return ntCondition;
1428 }
1429 
1431 {
1432  for ( WhenThen *cond : qgis::as_const( mConditions ) )
1433  {
1434  QVariant vWhen = cond->mWhenExp->eval( parent, context );
1435  QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( vWhen, parent );
1437  if ( tvl == QgsExpressionUtils::True )
1438  {
1439  QVariant vRes = cond->mThenExp->eval( parent, context );
1441  return vRes;
1442  }
1443  }
1444 
1445  if ( mElseExp )
1446  {
1447  QVariant vElse = mElseExp->eval( parent, context );
1449  return vElse;
1450  }
1451 
1452  // return NULL if no condition is matching
1453  return QVariant();
1454 }
1455 
1457 {
1458  bool res;
1459  for ( WhenThen *cond : qgis::as_const( mConditions ) )
1460  {
1461  res = cond->mWhenExp->prepare( parent, context )
1462  & cond->mThenExp->prepare( parent, context );
1463  if ( !res )
1464  return false;
1465  }
1466 
1467  if ( mElseExp )
1468  return mElseExp->prepare( parent, context );
1469 
1470  return true;
1471 }
1472 
1474 {
1475  QString msg( QStringLiteral( "CASE" ) );
1476  for ( WhenThen *cond : mConditions )
1477  {
1478  msg += QStringLiteral( " WHEN %1 THEN %2" ).arg( cond->mWhenExp->dump(), cond->mThenExp->dump() );
1479  }
1480  if ( mElseExp )
1481  msg += QStringLiteral( " ELSE %1" ).arg( mElseExp->dump() );
1482  msg += QLatin1String( " END" );
1483  return msg;
1484 }
1485 
1487 {
1488  QSet<QString> lst;
1489  for ( WhenThen *cond : mConditions )
1490  {
1491  lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
1492  }
1493 
1494  if ( mElseExp )
1495  lst += mElseExp->referencedColumns();
1496 
1497  return lst;
1498 }
1499 
1501 {
1502  QSet<QString> lst;
1503  for ( WhenThen *cond : mConditions )
1504  {
1505  lst += cond->mWhenExp->referencedVariables() + cond->mThenExp->referencedVariables();
1506  }
1507 
1508  if ( mElseExp )
1509  lst += mElseExp->referencedVariables();
1510 
1511  return lst;
1512 }
1513 
1515 {
1516  QSet<QString> lst;
1517  for ( WhenThen *cond : mConditions )
1518  {
1519  lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
1520  }
1521 
1522  if ( mElseExp )
1523  lst += mElseExp->referencedFunctions();
1524 
1525  return lst;
1526 }
1527 
1528 QList<const QgsExpressionNode *> QgsExpressionNodeCondition::nodes() const
1529 {
1530  QList<const QgsExpressionNode *> lst;
1531  lst << this;
1532  for ( WhenThen *cond : mConditions )
1533  {
1534  lst += cond->mWhenExp->nodes() + cond->mThenExp->nodes();
1535  }
1536 
1537  if ( mElseExp )
1538  lst += mElseExp->nodes();
1539 
1540  return lst;
1541 }
1542 
1544 {
1545  for ( WhenThen *cond : mConditions )
1546  {
1547  if ( cond->mWhenExp->needsGeometry() ||
1548  cond->mThenExp->needsGeometry() )
1549  return true;
1550  }
1551 
1552  return mElseExp && mElseExp->needsGeometry();
1553 }
1554 
1556 {
1558  for ( WhenThen *wt : mConditions )
1559  conditions.append( wt->clone() );
1560 
1561  QgsExpressionNodeCondition *copy = new QgsExpressionNodeCondition( conditions, mElseExp ? mElseExp->clone() : nullptr );
1562  cloneTo( copy );
1563  return copy;
1564 }
1565 
1567 {
1568  for ( WhenThen *wt : mConditions )
1569  {
1570  if ( !wt->mWhenExp->isStatic( parent, context ) || !wt->mThenExp->isStatic( parent, context ) )
1571  return false;
1572  }
1573 
1574  if ( mElseExp )
1575  return mElseExp->isStatic( parent, context );
1576 
1577  return true;
1578 }
1579 
1581 {
1582  QSet<QString> lst( mNode->referencedColumns() );
1583  const QList< QgsExpressionNode * > nodeList = mList->list();
1584  for ( const QgsExpressionNode *n : nodeList )
1585  lst.unite( n->referencedColumns() );
1586  return lst;
1587 }
1588 
1590 {
1591  QSet<QString> lst( mNode->referencedVariables() );
1592  const QList< QgsExpressionNode * > nodeList = mList->list();
1593  for ( const QgsExpressionNode *n : nodeList )
1594  lst.unite( n->referencedVariables() );
1595  return lst;
1596 }
1597 
1599 {
1600  QSet<QString> lst( mNode->referencedFunctions() );
1601  const QList< QgsExpressionNode * > nodeList = mList->list();
1602  for ( const QgsExpressionNode *n : nodeList )
1603  lst.unite( n->referencedFunctions() );
1604  return lst;
1605 }
1606 
1607 QList<const QgsExpressionNode *> QgsExpressionNodeInOperator::nodes() const
1608 {
1609  QList<const QgsExpressionNode *> lst;
1610  lst << this;
1611  const QList< QgsExpressionNode * > nodeList = mList->list();
1612  for ( const QgsExpressionNode *n : nodeList )
1613  lst += n->nodes();
1614  return lst;
1615 }
1616 
1618  : mWhenExp( whenExp )
1619  , mThenExp( thenExp )
1620 {
1621 }
1622 
1624 {
1625  delete mWhenExp;
1626  delete mThenExp;
1627 }
1628 
1630 {
1631  return new WhenThen( mWhenExp->clone(), mThenExp->clone() );
1632 }
1633 
1635 {
1636  return BINARY_OPERATOR_TEXT[mOp];
1637 }
1638 
1639 //
1640 
1642 {
1643  const QVariant container = mContainer->eval( parent, context );
1645  const QVariant index = mIndex->eval( parent, context );
1647 
1648  switch ( container.type() )
1649  {
1650  case QVariant::Map:
1651  return QgsExpressionUtils::getMapValue( container, parent ).value( index.toString() );
1652 
1653  case QVariant::List:
1654  case QVariant::StringList:
1655  {
1656  const QVariantList list = QgsExpressionUtils::getListValue( container, parent );
1657  qlonglong pos = QgsExpressionUtils::getIntValue( index, parent );
1658  if ( pos >= list.length() || pos < -list.length() )
1659  {
1660  return QVariant();
1661  }
1662  if ( pos < 0 )
1663  {
1664  // negative indices are from back of list
1665  pos += list.length();
1666  }
1667 
1668  return list.at( pos );
1669  }
1670 
1671  default:
1672  parent->setEvalErrorString( tr( "[] can only be used with map or array values, not %1" ).arg( QMetaType::typeName( container.type() ) ) );
1673  return QVariant();
1674  }
1675 }
1676 
1678 {
1679  return ntIndexOperator;
1680 }
1681 
1683 {
1684  bool resC = mContainer->prepare( parent, context );
1685  bool resV = mIndex->prepare( parent, context );
1686  return resC && resV;
1687 }
1688 
1690 {
1691  return QStringLiteral( "%1[%2]" ).arg( mContainer->dump(), mIndex->dump() );
1692 }
1693 
1695 {
1696  return mContainer->referencedColumns() + mIndex->referencedColumns();
1697 }
1698 
1700 {
1701  return mContainer->referencedVariables() + mIndex->referencedVariables();
1702 }
1703 
1705 {
1706  return mContainer->referencedFunctions() + mIndex->referencedFunctions();
1707 }
1708 
1709 QList<const QgsExpressionNode *> QgsExpressionNodeIndexOperator::nodes() const
1710 {
1711  QList<const QgsExpressionNode *> lst;
1712  lst << this;
1713  lst += mContainer->nodes() + mIndex->nodes();
1714  return lst;
1715 }
1716 
1718 {
1719  return mContainer->needsGeometry() || mIndex->needsGeometry();
1720 }
1721 
1723 {
1724  QgsExpressionNodeIndexOperator *copy = new QgsExpressionNodeIndexOperator( mContainer->clone(), mIndex->clone() );
1725  cloneTo( copy );
1726  return copy;
1727 }
1728 
1730 {
1731  return mContainer->isStatic( parent, context ) && mIndex->isStatic( parent, context );
1732 }
QgsExpressionNode::dump
virtual QString dump() const =0
Dump this node into a serialized (part) of an expression.
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:370
QgsExpressionNodeFunction::nodeType
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
Definition: qgsexpressionnodeimpl.cpp:1002
QgsExpressionNode::NamedNode::name
QString name
Node name.
Definition: qgsexpressionnode.h:107
QgsExpression::quotedString
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
Definition: qgsexpression.cpp:70
QgsInterval::seconds
double seconds() const
Returns the interval duration in seconds.
Definition: qgsinterval.h:168
QgsExpressionNodeFunction::needsGeometry
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
Definition: qgsexpressionnodeimpl.cpp:1117
QgsExpressionNodeBinaryOperator::prepareNode
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:678
QgsExpressionNode::cloneTo
void cloneTo(QgsExpressionNode *target) const
Copies the members of this node to the node provided in target.
Definition: qgsexpressionnode.cpp:51
QgsExpressionNodeLiteral::prepareNode
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:1229
QgsExpressionNodeIndexOperator::referencedVariables
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1699
qgsfeaturerequest.h
QgsExpressionNodeColumnRef::referencedVariables
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1374
QgsExpressionNodeLiteral
An expression node for literal values.
Definition: qgsexpressionnodeimpl.h:365
QgsExpressionNodeColumnRef::QgsExpressionNodeColumnRef
QgsExpressionNodeColumnRef(const QString &name)
Constructor for QgsExpressionNodeColumnRef, referencing the column with the specified name.
Definition: qgsexpressionnodeimpl.h:408
QgsExpressionNodeCondition::referencedFunctions
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1514
QgsExpressionNodeUnaryOperator::needsGeometry
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
Definition: qgsexpressionnodeimpl.cpp:173
QgsExpressionNodeBinaryOperator
A binary expression operator, which operates on two values.
Definition: qgsexpressionnodeimpl.h:92
QgsExpressionNodeBinaryOperator::dump
QString dump() const override
Dump this node into a serialized (part) of an expression.
Definition: qgsexpressionnodeimpl.cpp:767
QgsExpressionNodeColumnRef::referencedFunctions
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1379
QgsExpressionNodeUnaryOperator::clone
QgsExpressionNode * clone() const override
Generate a clone of this node.
Definition: qgsexpressionnodeimpl.cpp:178
QgsExpressionNodeCondition::prepareNode
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:1456
QgsExpressionNodeBinaryOperator::text
QString text() const
Returns a the name of this operator without the operands.
Definition: qgsexpressionnodeimpl.cpp:1634
qgsexpression.h
QgsExpressionNode::ntCondition
@ ntCondition
Definition: qgsexpressionnode.h:82
QgsExpressionNode::NodeType
NodeType
Known node types.
Definition: qgsexpressionnode.h:75
QgsExpressionNode::NodeList::hasNamedNodes
bool hasNamedNodes() const
Returns true if list contains any named nodes.
Definition: qgsexpressionnode.h:139
QgsExpressionNode::NamedNode::node
QgsExpressionNode * node
Node.
Definition: qgsexpressionnode.h:110
QgsExpressionNodeColumnRef::referencedColumns
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
Definition: qgsexpressionnodeimpl.cpp:1369
QgsExpressionNodeFunction::QgsExpressionNodeFunction
QgsExpressionNodeFunction(int fnIndex, QgsExpressionNode::NodeList *args)
A function node consists of an index of the function in the global function array and a list of argum...
Definition: qgsexpressionnodeimpl.cpp:957
QgsExpressionNode::ntColumnRef
@ ntColumnRef
Definition: qgsexpressionnode.h:81
QgsExpressionNodeUnaryOperator::evalNode
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:105
QgsExpressionNodeInOperator::~QgsExpressionNodeInOperator
~QgsExpressionNodeInOperator() override
Definition: qgsexpressionnodeimpl.cpp:894
QgsExpressionNodeColumnRef
An expression node which takes it value from a feature's field.
Definition: qgsexpressionnodeimpl.h:401
QgsExpressionNodeLiteral::value
QVariant value() const
The value of the literal.
Definition: qgsexpressionnodeimpl.h:376
QgsExpressionNodeFunction::fnIndex
int fnIndex() const
Returns the index of the node's function.
Definition: qgsexpressionnodeimpl.h:331
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:45
QgsExpressionNodeLiteral::nodeType
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
Definition: qgsexpressionnodeimpl.cpp:1224
QgsExpressionNodeUnaryOperator::nodeType
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
Definition: qgsexpressionnodeimpl.cpp:132
QgsExpressionNodeBinaryOperator::referencedColumns
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
Definition: qgsexpressionnodeimpl.cpp:798
QgsExpressionNodeCondition::WhenThen::WhenThen
WhenThen(QgsExpressionNode *whenExp, QgsExpressionNode *thenExp)
A combination of when and then.
Definition: qgsexpressionnodeimpl.cpp:1617
QgsExpressionNodeLiteral::nodes
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1274
QgsExpressionNodeUnaryOperator
A unary node is either negative as in boolean (not) or as in numbers (minus).
Definition: qgsexpressionnodeimpl.h:28
QgsExpressionNodeUnaryOperator::referencedVariables
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:155
QgsExpressionNodeIndexOperator::referencedColumns
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
Definition: qgsexpressionnodeimpl.cpp:1694
QgsExpressionNode::clone
virtual QgsExpressionNode * clone() const =0
Generate a clone of this node.
QgsExpressionNodeCondition
An expression node for CASE WHEN clauses.
Definition: qgsexpressionnodeimpl.h:441
QgsExpressionNodeFunction::clone
QgsExpressionNode * clone() const override
Generate a clone of this node.
Definition: qgsexpressionnodeimpl.cpp:1129
QgsExpressionNodeCondition::dump
QString dump() const override
Dump this node into a serialized (part) of an expression.
Definition: qgsexpressionnodeimpl.cpp:1473
QgsExpressionNodeLiteral::QgsExpressionNodeLiteral
QgsExpressionNodeLiteral(const QVariant &value)
Constructor for QgsExpressionNodeLiteral, with the specified literal value.
Definition: qgsexpressionnodeimpl.h:371
QgsExpressionNodeBinaryOperator::precedence
int precedence() const
Returns the precedence index for the operator.
Definition: qgsexpressionnodeimpl.cpp:685
QgsExpressionNodeInOperator::clone
QgsExpressionNode * clone() const override
Generate a clone of this node.
Definition: qgsexpressionnodeimpl.cpp:921
FALLTHROUGH
#define FALLTHROUGH
Definition: qgis.h:828
QgsExpressionNodeUnaryOperator::op
QgsExpressionNodeUnaryOperator::UnaryOperator op() const
Returns the unary operator.
Definition: qgsexpressionnodeimpl.h:53
QgsExpressionContext::variable
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
Definition: qgsexpressioncontext.cpp:296
QgsExpressionNodeCondition::evalNode
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:1430
QgsExpressionNodeIndexOperator::dump
QString dump() const override
Dump this node into a serialized (part) of an expression.
Definition: qgsexpressionnodeimpl.cpp:1689
QgsFeature::fieldNameIndex
int fieldNameIndex(const QString &fieldName) const
Utility method to get attribute index from name.
Definition: qgsfeature.cpp:279
QgsExpressionNodeInOperator
An expression node for value IN or NOT IN clauses.
Definition: qgsexpressionnodeimpl.h:265
QgsExpressionNodeCondition::referencedColumns
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
Definition: qgsexpressionnodeimpl.cpp:1486
QgsExpressionNodeUnaryOperator::text
QString text() const
Returns a the name of this operator without the operands.
Definition: qgsexpressionnodeimpl.cpp:190
QgsExpressionNodeUnaryOperator::referencedColumns
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
Definition: qgsexpressionnodeimpl.cpp:150
QgsExpressionFunction::referencedColumns
virtual QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const
Returns a set of field names which are required for this function.
Definition: qgsexpressionfunction.cpp:139
QgsExpressionNodeInOperator::needsGeometry
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
Definition: qgsexpressionnodeimpl.cpp:38
QgsExpressionNodeUnaryOperator::referencedFunctions
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:160
QgsExpressionNodeFunction::referencedColumns
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
Definition: qgsexpressionnodeimpl.cpp:1032
QgsExpressionNodeCondition::needsGeometry
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
Definition: qgsexpressionnodeimpl.cpp:1543
QgsExpressionNode::referencedFunctions
virtual QSet< QString > referencedFunctions() const =0
Returns a set of all functions which are used in this expression.
QgsExpressionNodeInOperator::prepareNode
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:905
QgsExpressionNodeColumnRef::isStatic
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
Definition: qgsexpressionnodeimpl.cpp:1403
QgsExpression::setEvalErrorString
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions)
Definition: qgsexpression.cpp:384
QgsExpressionNodeCondition::QgsExpressionNodeCondition
QgsExpressionNodeCondition(QgsExpressionNodeCondition::WhenThenList *conditions, QgsExpressionNode *elseExp=nullptr)
Create a new node with the given list of conditions and an optional elseExp expression.
Definition: qgsexpressionnodeimpl.cpp:1412
QgsExpressionNodeColumnRef::nodes
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1384
QgsExpressionNode::ntFunction
@ ntFunction
Definition: qgsexpressionnode.h:79
QgsExpressionFunction::params
int params() const
The number of parameters this function takes.
Definition: qgsexpressionfunction.h:193
QgsExpressionFunction::ParameterList
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
Definition: qgsexpressionfunction.h:104
QgsExpressionNodeLiteral::isStatic
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
Definition: qgsexpressionnodeimpl.cpp:1293
QgsExpressionNodeLiteral::referencedFunctions
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1269
QgsExpressionNode::eval
QVariant eval(QgsExpression *parent, const QgsExpressionContext *context)
Evaluate this node with the given context and parent.
Definition: qgsexpressionnode.cpp:20
QgsExpressionContext::EXPR_FIELDS
static const QString EXPR_FIELDS
Inbuilt variable name for fields storage.
Definition: qgsexpressioncontext.h:719
QgsExpressionNodeCondition::clone
QgsExpressionNode * clone() const override
Generate a clone of this node.
Definition: qgsexpressionnodeimpl.cpp:1555
QgsExpressionNodeColumnRef::evalNode
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:1302
QgsExpressionNodeFunction::args
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
Definition: qgsexpressionnodeimpl.h:336
QgsExpressionNodeBinaryOperator::referencedFunctions
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:808
QgsExpressionNodeIndexOperator::needsGeometry
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
Definition: qgsexpressionnodeimpl.cpp:1717
QgsFeature::isValid
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:185
QgsExpressionNodeFunction::referencedFunctions
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1085
QgsExpressionNodeBinaryOperator::referencedVariables
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:803
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsExpressionNode::referencedColumns
virtual QSet< QString > referencedColumns() const =0
Abstract virtual method which returns a list of columns required to evaluate this node.
QgsExpressionNodeBinaryOperator::clone
QgsExpressionNode * clone() const override
Generate a clone of this node.
Definition: qgsexpressionnodeimpl.cpp:826
QgsExpressionNodeInOperator::nodes
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1607
QgsExpressionNodeLiteral::dump
QString dump() const override
Dump this node into a serialized (part) of an expression.
Definition: qgsexpressionnodeimpl.cpp:1237
QgsExpressionNode::referencedVariables
virtual QSet< QString > referencedVariables() const =0
Returns a set of all variables which are used in this expression.
QgsExpressionNode::needsGeometry
virtual bool needsGeometry() const =0
Abstract virtual method which returns if the geometry is required to evaluate this expression.
QgsExpressionNodeCondition::nodes
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1528
QgsExpressionNodeCondition::conditions
WhenThenList conditions() const
The list of WHEN THEN expression parts of the expression.
Definition: qgsexpressionnodeimpl.h:516
QgsExpressionNodeFunction::prepareNode
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:1007
qgsexpressionutils.h
ENSURE_NO_EVAL_ERROR
#define ENSURE_NO_EVAL_ERROR
Definition: qgsexpressionutils.h:31
QgsExpressionNodeIndexOperator::referencedFunctions
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1704
QgsExpressionNodeColumnRef::dump
QString dump() const override
Dump this node into a serialized (part) of an expression.
Definition: qgsexpressionnodeimpl.cpp:1364
QgsExpressionNodeFunction::dump
QString dump() const override
Dump this node into a serialized (part) of an expression.
Definition: qgsexpressionnodeimpl.cpp:1023
QgsExpressionNodeLiteral::referencedColumns
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
Definition: qgsexpressionnodeimpl.cpp:1259
QgsFeature::attribute
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:264
SET_EVAL_ERROR
#define SET_EVAL_ERROR(x)
Definition: qgsexpressionutils.h:32
typeName
const QString & typeName
Definition: qgswfsgetfeature.cpp:55
QgsExpressionNode::ntBinaryOperator
@ ntBinaryOperator
Definition: qgsexpressionnode.h:77
QgsExpressionContext::function
QgsExpressionFunction * function(const QString &name) const
Fetches a matching function from the context.
Definition: qgsexpressioncontext.cpp:472
QgsExpressionNodeBinaryOperator::evalNode
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:197
QgsExpressionNodeFunction
An expression node for expression functions.
Definition: qgsexpressionnodeimpl.h:317
QgsExpressionNodeUnaryOperator::isStatic
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
Definition: qgsexpressionnodeimpl.cpp:185
QgsExpressionNode::ntLiteral
@ ntLiteral
Definition: qgsexpressionnode.h:80
QgsExpression::Functions
static const QList< QgsExpressionFunction * > & Functions()
Definition: qgsexpressionfunction.cpp:6008
QgsExpressionNodeInOperator::referencedColumns
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
Definition: qgsexpressionnodeimpl.cpp:1580
QgsExpressionNodeIndexOperator::isStatic
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
Definition: qgsexpressionnodeimpl.cpp:1729
QgsExpressionNodeUnaryOperator::uoNot
@ uoNot
Definition: qgsexpressionnodeimpl.h:37
QgsExpressionFunction::prepare
virtual bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
This will be called during the prepare step() of an expression if it is not static.
Definition: qgsexpressionfunction.cpp:131
QgsExpressionNodeBinaryOperator::nodes
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:813
QgsExpressionNodeFunction::validateParams
static bool validateParams(int fnIndex, QgsExpressionNode::NodeList *args, QString &error)
Tests whether the provided argument list is valid for the matching function.
Definition: qgsexpressionnodeimpl.cpp:1141
QgsExpressionNodeColumnRef::clone
QgsExpressionNode * clone() const override
Generate a clone of this node.
Definition: qgsexpressionnodeimpl.cpp:1396
QgsExpressionNode::NodeList::list
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
Definition: qgsexpressionnode.h:144
QgsExpressionNode
Abstract base class for all nodes that can appear in an expression.
Definition: qgsexpressionnode.h:35
QgsExpressionNodeInOperator::isStatic
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
Definition: qgsexpressionnodeimpl.cpp:928
QgsExpressionNode::NodeList::clone
QgsExpressionNode::NodeList * clone() const
Creates a deep copy of this list. Ownership is transferred to the caller.
Definition: qgsexpressionnodeimpl.cpp:60
QgsExpressionNodeInOperator::evalNode
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:840
QgsExpressionNode::isStatic
virtual bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const =0
Returns true if this node can be evaluated for a static value.
QgsExpressionNodeCondition::nodeType
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
Definition: qgsexpressionnodeimpl.cpp:1425
QgsExpressionNodeColumnRef::nodeType
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
Definition: qgsexpressionnodeimpl.cpp:1337
QgsExpressionNodeUnaryOperator::nodes
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:165
QgsExpressionNode::NodeList::dump
virtual QString dump() const
Returns a string dump of the expression node.
Definition: qgsexpressionnodeimpl.cpp:72
QgsExpressionFunction::lazyEval
bool lazyEval() const
true if this function should use lazy evaluation.
Definition: qgsexpressionfunction.h:232
qgsgeometry.h
QgsExpressionNodeCondition::WhenThen::clone
QgsExpressionNodeCondition::WhenThen * clone() const
Gets a deep copy of this WhenThen combination.
Definition: qgsexpressionnodeimpl.cpp:1629
QgsExpressionNodeLiteral::evalNode
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:1217
qgsexpressionnodeimpl.h
QgsExpressionFunction::run
virtual QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
Evaluates the function, first evaluating all required arguments before passing them to the function's...
Definition: qgsexpressionfunction.cpp:79
QgsExpressionFunction
A abstract base class for defining QgsExpression functions.
Definition: qgsexpressionfunction.h:41
QgsExpressionNode::ntUnaryOperator
@ ntUnaryOperator
Definition: qgsexpressionnode.h:76
QgsExpressionNode::NodeList::append
void append(QgsExpressionNode *node)
Takes ownership of the provided node.
Definition: qgsexpressionnode.h:122
QgsExpressionNodeInOperator::dump
QString dump() const override
Dump this node into a serialized (part) of an expression.
Definition: qgsexpressionnodeimpl.cpp:916
QgsExpressionNodeColumnRef::prepareNode
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:1342
QgsExpressionContext::feature
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
Definition: qgsexpressioncontext.cpp:540
QgsInterval
A representation of the interval between two datetime values.
Definition: qgsinterval.h:41
QgsExpressionNodeCondition::WhenThen
Represents a "WHEN... THEN..." portation of a CASE WHEN clause in an expression.
Definition: qgsexpressionnodeimpl.h:449
QgsExpressionFunction::name
QString name() const
The name of the function.
Definition: qgsexpressionfunction.h:190
QgsExpressionFunction::parameters
const QgsExpressionFunction::ParameterList & parameters() const
Returns the list of named parameters for the function, if set.
Definition: qgsexpressionfunction.h:214
QgsExpressionNodeBinaryOperator::isStatic
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
Definition: qgsexpressionnodeimpl.cpp:833
QgsExpression::quotedColumnRef
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
Definition: qgsexpression.cpp:65
QgsExpressionNodeUnaryOperator::dump
QString dump() const override
Dump this node into a serialized (part) of an expression.
Definition: qgsexpressionnodeimpl.cpp:142
QgsExpressionNodeFunction::referencedVariables
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1055
QgsExpressionNodeFunction::nodes
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1102
QgsExpressionNodeBinaryOperator::needsGeometry
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
Definition: qgsexpressionnodeimpl.cpp:821
QgsExpressionNodeColumnRef::needsGeometry
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
Definition: qgsexpressionnodeimpl.cpp:1391
QgsExpressionNodeFunction::evalNode
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:945
QgsExpressionNodeInOperator::nodeType
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
Definition: qgsexpressionnodeimpl.cpp:900
QgsExpressionNodeInOperator::referencedVariables
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1589
QgsExpressionNodeUnaryOperator::prepareNode
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:137
QgsExpressionNodeFunction::~QgsExpressionNodeFunction
~QgsExpressionNodeFunction() override
Definition: qgsexpressionnodeimpl.cpp:997
QgsExpressionNodeIndexOperator::evalNode
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:1641
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsExpressionNodeCondition::~QgsExpressionNodeCondition
~QgsExpressionNodeCondition() override
Definition: qgsexpressionnodeimpl.cpp:1419
QgsExpressionNodeIndexOperator::clone
QgsExpressionNode * clone() const override
Generate a clone of this node.
Definition: qgsexpressionnodeimpl.cpp:1722
QgsExpressionNode::nodes
virtual QList< const QgsExpressionNode * > nodes() const =0
Returns a list of all nodes which are used in this expression.
QgsExpressionNodeCondition::isStatic
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
Definition: qgsexpressionnodeimpl.cpp:1566
QgsExpressionNodeLiteral::clone
QgsExpressionNode * clone() const override
Generate a clone of this node.
Definition: qgsexpressionnodeimpl.cpp:1286
QgsExpressionContext::hasFunction
bool hasFunction(const QString &name) const
Checks whether a specified function is contained in the context.
Definition: qgsexpressioncontext.cpp:448
QgsExpressionNodeIndexOperator::nodeType
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
Definition: qgsexpressionnodeimpl.cpp:1677
QgsExpressionNodeIndexOperator
A indexing expression operator, which allows use of square brackets [] to reference map and array ite...
Definition: qgsexpressionnodeimpl.h:215
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:344
QgsExpression
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:105
QgsExpressionNode::NodeList::~NodeList
virtual ~NodeList()
Definition: qgsexpressionnodeimpl.cpp:47
QgsExpressionNode::prepare
bool prepare(QgsExpression *parent, const QgsExpressionContext *context)
Prepare this node for evaluation.
Definition: qgsexpressionnode.cpp:33
QgsExpressionNode::NamedNode
Named node.
Definition: qgsexpressionnode.h:93
QgsExpressionNodeBinaryOperator::nodeType
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
Definition: qgsexpressionnodeimpl.cpp:673
QgsExpressionNodeFunction::isStatic
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
Definition: qgsexpressionnodeimpl.cpp:1136
QgsExpressionNode::ntIndexOperator
@ ntIndexOperator
Index operator.
Definition: qgsexpressionnode.h:83
QgsExpressionNodeLiteral::needsGeometry
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
Definition: qgsexpressionnodeimpl.cpp:1281
QgsExpressionNodeInOperator::referencedFunctions
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1598
QgsExpressionNodeIndexOperator::nodes
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1709
QgsExpressionNode::NodeList::names
QStringList names() const
Returns a list of names for nodes.
Definition: qgsexpressionnode.h:157
QgsExpressionNodeIndexOperator::prepareNode
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
Definition: qgsexpressionnodeimpl.cpp:1682
QgsExpressionNode::NodeList
A list of expression nodes.
Definition: qgsexpressionnode.h:118
QgsExpressionContext::hasVariable
bool hasVariable(const QString &name) const
Check whether a variable is specified by any scope within the context.
Definition: qgsexpressioncontext.cpp:285
QgsExpressionNodeCondition::WhenThen::~WhenThen
~WhenThen()
Definition: qgsexpressionnodeimpl.cpp:1623
QgsExpressionNodeCondition::WhenThenList
QList< QgsExpressionNodeCondition::WhenThen * > WhenThenList
Definition: qgsexpressionnodeimpl.h:490
QgsExpressionNodeLiteral::referencedVariables
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1264
QgsExpressionContext::hasFeature
bool hasFeature() const
Returns true if the context has a feature associated with it.
Definition: qgsexpressioncontext.cpp:529
QgsExpressionNode::ntInOperator
@ ntInOperator
Definition: qgsexpressionnode.h:78
QgsExpressionNodeCondition::referencedVariables
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
Definition: qgsexpressionnodeimpl.cpp:1500
QgsExpressionNodeBinaryOperator::leftAssociative
bool leftAssociative() const
Returns true if the operator is left-associative.
Definition: qgsexpressionnodeimpl.cpp:731