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