QGIS API Documentation
qgsexpression.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpression.h
3  -------------------
4  begin : August 2011
5  copyright : (C) 2011 Martin Dobias
6  email : wonder.sk at gmail dot com
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 #ifndef QGSEXPRESSION_H
17 #define QGSEXPRESSION_H
18 
19 #include <QMetaType>
20 #include <QStringList>
21 #include <QVariant>
22 #include <QList>
23 #include <QDomDocument>
24 #include <QCoreApplication>
25 #include <QSet>
26 
27 #include "qgis.h"
28 #include "qgsunittypes.h"
29 
30 class QgsFeature;
31 class QgsGeometry;
32 class QgsOgcUtils;
33 class QgsVectorLayer;
35 class QgsField;
36 class QgsFields;
37 class QgsDistanceArea;
38 class QDomElement;
40 class QgsExpressionPrivate;
41 
108 class CORE_EXPORT QgsExpression
109 {
110  Q_DECLARE_TR_FUNCTIONS( QgsExpression )
111  public:
118  QgsExpression( const QString& expr );
119 
125  QgsExpression( const QgsExpression& other );
131  QgsExpression& operator=( const QgsExpression& other );
132  ~QgsExpression();
133 
135  bool hasParserError() const;
137  QString parserErrorString() const;
138 
139  class Node;
140 
142  const Node* rootNode() const;
143 
146  Q_DECL_DEPRECATED bool prepare( const QgsFields &fields );
147 
152  bool prepare( const QgsExpressionContext *context );
153 
162  QStringList referencedColumns() const;
163 
165  bool needsGeometry() const;
166 
167  // evaluation
168 
172  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature* f );
173 
178  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature& f );
179 
183  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature* f, const QgsFields& fields );
184 
189  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature& f, const QgsFields& fields );
190 
195  QVariant evaluate();
196 
202  QVariant evaluate( const QgsExpressionContext* context );
203 
205  bool hasEvalError() const;
207  QString evalErrorString() const;
209  void setEvalErrorString( const QString& str );
210 
213  Q_DECL_DEPRECATED void setCurrentRowNumber( int rowNumber );
216  Q_DECL_DEPRECATED int currentRowNumber(); //TODO QGIS 3.0: make the following methods private. They are still required for replaceExpressionText
217  //but should not be publicly used
221  Q_DECL_DEPRECATED static void setSpecialColumn( const QString& name, const QVariant& value );
225  Q_DECL_DEPRECATED static void unsetSpecialColumn( const QString& name );
229  Q_DECL_DEPRECATED static QVariant specialColumn( const QString& name );
230 
234  static bool hasSpecialColumn( const QString& name );
235 
239  bool isField() const { return rootNode() && dynamic_cast<const NodeColumnRef*>( rootNode() ) ;}
240 
242  Q_DECL_DEPRECATED static bool isValid( const QString& text, const QgsFields& fields, QString &errorMessage );
243 
251  static bool isValid( const QString& text, const QgsExpressionContext* context, QString &errorMessage );
252 
253  void setScale( double scale );
254 
255  double scale();
256 
260  QString expression() const;
261 
266  QString dump() const;
267 
274  QgsDistanceArea *geomCalculator();
275 
282  //TODO QGIS 3.0 change calc to a pointer, so that calculator can be cleared by passing nullptr
283  void setGeomCalculator( const QgsDistanceArea &calc );
284 
291  QGis::UnitType distanceUnits() const;
292 
299  void setDistanceUnits( QGis::UnitType unit );
300 
307  QgsUnitTypes::AreaUnit areaUnits() const;
308 
315  void setAreaUnits( QgsUnitTypes::AreaUnit unit );
316 
330  Q_DECL_DEPRECATED static QString replaceExpressionText( const QString &action, const QgsFeature *feat,
331  QgsVectorLayer *layer,
332  const QMap<QString, QVariant> *substitutionMap = nullptr,
333  const QgsDistanceArea* distanceArea = nullptr );
334 
346  static QString replaceExpressionText( const QString &action, const QgsExpressionContext* context,
347  const QMap<QString, QVariant> *substitutionMap = nullptr,
348  const QgsDistanceArea* distanceArea = nullptr );
349 
359  static double evaluateToDouble( const QString& text, const double fallbackValue );
360 
366  {
369  };
370 
376  {
377  // logical
380 
381  // comparison
382  boEQ, // =
383  boNE, // <>
384  boLE, // <=
385  boGE, // >=
386  boLT, // <
387  boGT, // >
395 
396  // math
404 
405  // strings
407  };
408 
410  {
420  };
421 
423  static const char* BinaryOperatorText[];
424 
426  static const char* UnaryOperatorText[];
427 
432  class CORE_EXPORT Parameter
433  {
434  public:
435 
441  Parameter( const QString& name,
442  bool optional = false,
443  const QVariant& defaultValue = QVariant() )
444  : mName( name )
445  , mOptional( optional )
446  , mDefaultValue( defaultValue )
447  {}
448 
450  QString name() const { return mName; }
451 
453  bool optional() const { return mOptional; }
454 
456  QVariant defaultValue() const { return mDefaultValue; }
457 
458  bool operator==( const Parameter& other ) const
459  {
460  return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
461  }
462 
463  private:
464  QString mName;
465  bool mOptional;
466  QVariant mDefaultValue;
467  };
468 
471 
473  typedef QVariant( *FcnEval )( const QVariantList& values, const QgsFeature* f, QgsExpression* parent );
474 
477  typedef QVariant( *FcnEvalContext )( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent );
478 
482  class CORE_EXPORT Function
483  {
484  public:
485 
487  Function( const QString& fnname,
488  int params,
489  const QString& group,
490  const QString& helpText = QString(),
491  bool usesGeometry = false,
492  const QStringList& referencedColumns = QStringList(),
493  bool lazyEval = false,
494  bool handlesNull = false,
495  bool isContextual = false )
496  : mName( fnname )
497  , mParams( params )
498  , mUsesGeometry( usesGeometry )
499  , mGroup( group )
500  , mHelpText( helpText )
501  , mReferencedColumns( referencedColumns )
502  , mLazyEval( lazyEval )
503  , mHandlesNull( handlesNull )
504  , mIsContextual( isContextual )
505  {
506  }
507 
511  Function( const QString& fnname,
512  const ParameterList& params,
513  const QString& group,
514  const QString& helpText = QString(),
515  bool usesGeometry = false,
516  const QStringList& referencedColumns = QStringList(),
517  bool lazyEval = false,
518  bool handlesNull = false,
519  bool isContextual = false )
520  : mName( fnname )
521  , mParams( 0 )
522  , mParameterList( params )
523  , mUsesGeometry( usesGeometry )
524  , mGroup( group )
525  , mHelpText( helpText )
526  , mReferencedColumns( referencedColumns )
527  , mLazyEval( lazyEval )
528  , mHandlesNull( handlesNull )
529  , mIsContextual( isContextual )
530  {}
531 
532  virtual ~Function() {}
533 
535  QString name() const { return mName; }
536 
538  int params() const { return mParameterList.isEmpty() ? mParams : mParameterList.count(); }
539 
541  int minParams() const
542  {
543  if ( mParameterList.isEmpty() )
544  return mParams;
545 
546  int min = 0;
547  Q_FOREACH ( const Parameter& param, mParameterList )
548  {
549  if ( !param.optional() )
550  min++;
551  }
552  return min;
553  }
554 
558  const ParameterList& parameters() const { return mParameterList; }
559 
561  //TODO QGIS 3.0 - rename to usesGeometry()
562  bool usesgeometry() const { return mUsesGeometry; }
563 
569  virtual QStringList aliases() const { return QStringList(); }
570 
574  bool lazyEval() const { return mLazyEval; }
575 
576  virtual QStringList referencedColumns() const { return mReferencedColumns; }
577 
581  bool isContextual() const { return mIsContextual; }
582 
584  QString group() const { return mGroup; }
586  //TODO QGIS 3.0 - rename to helpText()
587  const QString helptext() const { return mHelpText.isEmpty() ? QgsExpression::helptext( mName ) : mHelpText; }
588 
590  Q_DECL_DEPRECATED virtual QVariant func( const QVariantList&, const QgsFeature*, QgsExpression* );
591 
599  //TODO QGIS 3.0 - rename python method
600  virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent );
601 
602  bool operator==( const Function& other ) const
603  {
604  if ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 )
605  return true;
606 
607  return false;
608  }
609 
610  virtual bool handlesNull() const { return mHandlesNull; }
611 
612  private:
613  QString mName;
614  int mParams;
615  ParameterList mParameterList;
616  bool mUsesGeometry;
617  QString mGroup;
618  QString mHelpText;
619  QStringList mReferencedColumns;
620  bool mLazyEval;
621  bool mHandlesNull;
622  bool mIsContextual; //if true function is only available through an expression context
623  };
624 
629  class StaticFunction : public Function
630  {
631  public:
633  Q_DECL_DEPRECATED StaticFunction( const QString& fnname,
634  int params,
635  FcnEval fcn,
636  const QString& group,
637  const QString& helpText = QString(),
638  bool usesGeometry = false,
639  const QStringList& referencedColumns = QStringList(),
640  bool lazyEval = false,
641  const QStringList& aliases = QStringList(),
642  bool handlesNull = false )
643  : Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval, handlesNull )
644  , mFnc( fcn )
645  , mContextFnc( nullptr )
646  , mAliases( aliases )
647  {}
648 
649  virtual ~StaticFunction() {}
650 
653  StaticFunction( const QString& fnname,
654  int params,
655  FcnEvalContext fcn,
656  const QString& group,
657  const QString& helpText = QString(),
658  bool usesGeometry = false,
659  const QStringList& referencedColumns = QStringList(),
660  bool lazyEval = false,
661  const QStringList& aliases = QStringList(),
662  bool handlesNull = false )
663  : Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval, handlesNull )
664  , mFnc( nullptr )
665  , mContextFnc( fcn )
666  , mAliases( aliases )
667  {}
668 
671  StaticFunction( const QString& fnname,
672  const ParameterList& params,
673  FcnEvalContext fcn,
674  const QString& group,
675  const QString& helpText = QString(),
676  bool usesGeometry = false,
677  const QStringList& referencedColumns = QStringList(),
678  bool lazyEval = false,
679  const QStringList& aliases = QStringList(),
680  bool handlesNull = false )
681  : Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval, handlesNull )
682  , mFnc( nullptr )
683  , mContextFnc( fcn )
684  , mAliases( aliases )
685  {}
686 
688  Q_DECL_DEPRECATED virtual QVariant func( const QVariantList& values, const QgsFeature* f, QgsExpression* parent ) override;
689 
696  virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent ) override
697  {
698  return mContextFnc ? mContextFnc( values, context, parent ) : QVariant();
699  }
700 
701  virtual QStringList aliases() const override { return mAliases; }
702 
703  private:
704  FcnEval mFnc;
705  FcnEvalContext mContextFnc;
706  QStringList mAliases;
707  };
708 
711  static const QList<Function*>& Functions();
712 
715  static const QStringList& BuiltinFunctions();
716 
723  static bool registerFunction( Function* function, bool transferOwnership = false );
724 
729  static bool unregisterFunction( const QString& name );
730 
734 
738  static void cleanRegisteredFunctions();
739 
741  static bool isFunctionName( const QString& name );
742 
744  static int functionIndex( const QString& name );
745 
749  static int functionCount();
750 
754  static QList<Function*> specialColumns();
755 
760  static QString quotedColumnRef( QString name );
761 
766  static QString quotedString( QString text );
767 
775  static QString quotedValue( const QVariant& value );
776 
785  static QString quotedValue( const QVariant& value, QVariant::Type type );
786 
788 
789  class Visitor; // visitor interface is defined below
790 
791  enum NodeType
792  {
799  ntCondition
800  };
801 
802  class CORE_EXPORT Node
803  {
804  public:
805  virtual ~Node() {}
806 
812  virtual NodeType nodeType() const = 0;
813 
819  Q_DECL_DEPRECATED virtual QVariant eval( QgsExpression* parent, const QgsFeature* f );
820 
826  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context );
827 
833  Q_DECL_DEPRECATED virtual bool prepare( QgsExpression* parent, const QgsFields &fields );
834 
840  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context );
841 
847  virtual QString dump() const = 0;
848 
857  virtual Node* clone() const = 0;
858 
869  virtual QStringList referencedColumns() const = 0;
870 
879  virtual bool needsGeometry() const = 0;
880 
896  virtual void accept( Visitor& v ) const = 0;
897  };
898 
901  class CORE_EXPORT NamedNode
902  {
903  public:
904 
909  NamedNode( const QString& name, Node* node )
910  : name( name )
911  , node( node )
912  {}
913 
916 
919  };
920 
921  class CORE_EXPORT NodeList
922  {
923  public:
924  NodeList() : mHasNamedNodes( false ) {}
925  virtual ~NodeList() { qDeleteAll( mList ); }
927  void append( Node* node ) { mList.append( node ); mNameList.append( QString() ); }
928 
932  void append( NamedNode* node ) { mList.append( node->node ); mNameList.append( node->name.toLower() ); mHasNamedNodes = true; }
933 
936  int count() const { return mList.count(); }
937 
940  bool hasNamedNodes() const { return mHasNamedNodes; }
941 
942  QList<Node*> list() { return mList; }
943 
946  QStringList names() const { return mNameList; }
947 
949  NodeList* clone() const;
950 
951  virtual QString dump() const;
952 
953  protected:
956 
957  private:
958 
959  bool mHasNamedNodes;
960  };
961 
962  class CORE_EXPORT Interval
963  {
964  // YEAR const value taken from postgres query
965  // SELECT EXTRACT(EPOCH FROM interval '1 year')
966  static const int YEARS = 31557600;
967  static const int MONTHS = 60 * 60 * 24 * 30;
968  static const int WEEKS = 60 * 60 * 24 * 7;
969  static const int DAY = 60 * 60 * 24;
970  static const int HOUR = 60 * 60;
971  static const int MINUTE = 60;
972  public:
973  Interval( double seconds = 0 )
974  : mSeconds( seconds )
975  , mValid( true )
976  { }
977 
979  double years() { return mSeconds / YEARS;}
981  double months() { return mSeconds / MONTHS; }
983  double weeks() { return mSeconds / WEEKS;}
985  double days() { return mSeconds / DAY;}
987  double hours() { return mSeconds / HOUR;}
989  double minutes() { return mSeconds / MINUTE;}
991  double seconds() { return mSeconds; }
993  bool isValid() { return mValid; }
995  void setValid( bool valid ) { mValid = valid; }
997  bool operator==( QgsExpression::Interval other ) const;
999  static QgsExpression::Interval invalidInterVal();
1001  static QgsExpression::Interval fromString( const QString& string );
1002 
1003  private:
1004  double mSeconds;
1005  bool mValid;
1006  };
1007 
1008  class CORE_EXPORT NodeUnaryOperator : public Node
1009  {
1010  public:
1012  : mOp( op )
1013  , mOperand( operand )
1014  {}
1015  ~NodeUnaryOperator() { delete mOperand; }
1016 
1017  UnaryOperator op() const { return mOp; }
1018  Node* operand() const { return mOperand; }
1019 
1020  virtual NodeType nodeType() const override { return ntUnaryOperator; }
1021  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1022  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1023  virtual QString dump() const override;
1024 
1025  virtual QStringList referencedColumns() const override { return mOperand->referencedColumns(); }
1026  virtual bool needsGeometry() const override { return mOperand->needsGeometry(); }
1027  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1028  virtual Node* clone() const override;
1029 
1030  protected:
1033  };
1034 
1035  class CORE_EXPORT NodeBinaryOperator : public Node
1036  {
1037  public:
1038  NodeBinaryOperator( BinaryOperator op, Node* opLeft, Node* opRight )
1039  : mOp( op )
1040  , mOpLeft( opLeft )
1041  , mOpRight( opRight )
1042  {}
1043  ~NodeBinaryOperator() { delete mOpLeft; delete mOpRight; }
1044 
1045  BinaryOperator op() const { return mOp; }
1046  Node* opLeft() const { return mOpLeft; }
1047  Node* opRight() const { return mOpRight; }
1048 
1049  virtual NodeType nodeType() const override { return ntBinaryOperator; }
1050  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1051  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1052  virtual QString dump() const override;
1053 
1054  virtual QStringList referencedColumns() const override { return mOpLeft->referencedColumns() + mOpRight->referencedColumns(); }
1055  virtual bool needsGeometry() const override { return mOpLeft->needsGeometry() || mOpRight->needsGeometry(); }
1056  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1057  virtual Node* clone() const override;
1058 
1059  int precedence() const;
1060  bool leftAssociative() const;
1061 
1062  protected:
1063  bool compare( double diff );
1064  int computeInt( int x, int y );
1065  double computeDouble( double x, double y );
1066  QDateTime computeDateTimeFromInterval( const QDateTime& d, QgsExpression::Interval *i );
1067 
1071  };
1072 
1073  class CORE_EXPORT NodeInOperator : public Node
1074  {
1075  public:
1076  NodeInOperator( Node* node, NodeList* list, bool notin = false )
1077  : mNode( node )
1078  , mList( list )
1079  , mNotIn( notin )
1080  {}
1081  virtual ~NodeInOperator() { delete mNode; delete mList; }
1082 
1083  Node* node() const { return mNode; }
1084  bool isNotIn() const { return mNotIn; }
1085  NodeList* list() const { return mList; }
1086 
1087  virtual NodeType nodeType() const override { return ntInOperator; }
1088  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1089  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1090  virtual QString dump() const override;
1091 
1092  virtual QStringList referencedColumns() const override { QStringList lst( mNode->referencedColumns() ); Q_FOREACH ( const Node* n, mList->list() ) lst.append( n->referencedColumns() ); return lst; }
1093  virtual bool needsGeometry() const override { bool needs = false; Q_FOREACH ( Node* n, mList->list() ) needs |= n->needsGeometry(); return needs; }
1094  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1095  virtual Node* clone() const override;
1096 
1097  protected:
1100  bool mNotIn;
1101  };
1102 
1103  class CORE_EXPORT NodeFunction : public Node
1104  {
1105  public:
1106  NodeFunction( int fnIndex, NodeList* args ) : mFnIndex( fnIndex )
1107  {
1108  const ParameterList& functionParams = Functions()[mFnIndex]->parameters();
1109  if ( !args || !args->hasNamedNodes() || functionParams.isEmpty() )
1110  {
1111  // no named parameters, or function does not support them
1112  mArgs = args;
1113  }
1114  else
1115  {
1116  mArgs = new NodeList();
1117 
1118  int idx = 0;
1119  //first loop through unnamed arguments
1120  while ( args->names().at( idx ).isEmpty() )
1121  {
1122  mArgs->append( args->list().at( idx )->clone() );
1123  idx++;
1124  }
1125 
1126  //next copy named parameters in order expected by function
1127  for ( ; idx < functionParams.count(); ++idx )
1128  {
1129  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1130  if ( nodeIdx < 0 )
1131  {
1132  //parameter not found - insert default value for parameter
1133  mArgs->append( new NodeLiteral( functionParams.at( idx ).defaultValue() ) );
1134  }
1135  else
1136  {
1137  mArgs->append( args->list().at( nodeIdx )->clone() );
1138  }
1139  }
1140 
1141  delete args;
1142  }
1143  }
1144 
1145  virtual ~NodeFunction() { delete mArgs; }
1146 
1147  int fnIndex() const { return mFnIndex; }
1148  NodeList* args() const { return mArgs; }
1149 
1150  virtual NodeType nodeType() const override { return ntFunction; }
1151  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1152  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1153  virtual QString dump() const override;
1154 
1155  virtual QStringList referencedColumns() const override;
1156  virtual bool needsGeometry() const override { bool needs = Functions()[mFnIndex]->usesgeometry(); if ( mArgs ) { Q_FOREACH ( Node* n, mArgs->list() ) needs |= n->needsGeometry(); } return needs; }
1157  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1158  virtual Node* clone() const override;
1159 
1161  static bool validateParams( int fnIndex, NodeList* args, QString& error )
1162  {
1163  if ( !args || !args->hasNamedNodes() )
1164  return true;
1165 
1166  const ParameterList& functionParams = Functions()[fnIndex]->parameters();
1167  if ( functionParams.isEmpty() )
1168  {
1169  error = QString( "%1 does not supported named parameters" ).arg( Functions()[fnIndex]->name() );
1170  return false;
1171  }
1172  else
1173  {
1174  QSet< int > providedArgs;
1175  QSet< int > handledArgs;
1176  int idx = 0;
1177  //first loop through unnamed arguments
1178  while ( args->names().at( idx ).isEmpty() )
1179  {
1180  providedArgs << idx;
1181  handledArgs << idx;
1182  idx++;
1183  }
1184 
1185  //next check named parameters
1186  for ( ; idx < functionParams.count(); ++idx )
1187  {
1188  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1189  if ( nodeIdx < 0 )
1190  {
1191  if ( !functionParams.at( idx ).optional() )
1192  {
1193  error = QString( "No value specified for parameter '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
1194  return false;
1195  }
1196  }
1197  else
1198  {
1199  if ( providedArgs.contains( idx ) )
1200  {
1201  error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
1202  return false;
1203  }
1204  }
1205  providedArgs << idx;
1206  handledArgs << nodeIdx;
1207  }
1208 
1209  //last check for bad names
1210  idx = 0;
1211  Q_FOREACH ( const QString& name, args->names() )
1212  {
1213  if ( !name.isEmpty() && !functionParams.contains( name ) )
1214  {
1215  error = QString( "Invalid parameter name '%1' for %2" ).arg( name, Functions()[fnIndex]->name() );
1216  return false;
1217  }
1218  if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1219  {
1220  int functionIdx = functionParams.indexOf( name );
1221  if ( providedArgs.contains( functionIdx ) )
1222  {
1223  error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(), Functions()[fnIndex]->name() );
1224  return false;
1225  }
1226  }
1227  idx++;
1228  }
1229 
1230  }
1231  return true;
1232  }
1233 
1234  protected:
1237 
1238  };
1239 
1240  class CORE_EXPORT NodeLiteral : public Node
1241  {
1242  public:
1243  NodeLiteral( const QVariant& value )
1244  : mValue( value )
1245  {}
1246 
1248  inline QVariant value() const { return mValue; }
1249 
1250  virtual NodeType nodeType() const override { return ntLiteral; }
1251  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1252  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1253  virtual QString dump() const override;
1254 
1255  virtual QStringList referencedColumns() const override { return QStringList(); }
1256  virtual bool needsGeometry() const override { return false; }
1257  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1258  virtual Node* clone() const override;
1259 
1260  protected:
1262  };
1263 
1264  class CORE_EXPORT NodeColumnRef : public Node
1265  {
1266  public:
1267  NodeColumnRef( const QString& name )
1268  : mName( name )
1269  , mIndex( -1 )
1270  {}
1271 
1273  QString name() const { return mName; }
1274 
1275  virtual NodeType nodeType() const override { return ntColumnRef; }
1276  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1277  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1278  virtual QString dump() const override;
1279 
1280  virtual QStringList referencedColumns() const override { return QStringList( mName ); }
1281  virtual bool needsGeometry() const override { return false; }
1282 
1283  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1284  virtual Node* clone() const override;
1285 
1286  protected:
1288  int mIndex;
1289  };
1290 
1291  class CORE_EXPORT WhenThen
1292  {
1293  public:
1294  WhenThen( Node* whenExp, Node* thenExp )
1295  : mWhenExp( whenExp )
1296  , mThenExp( thenExp )
1297  {}
1298  ~WhenThen() { delete mWhenExp; delete mThenExp; }
1299 
1300  // protected:
1303 
1304  private:
1305  WhenThen( const WhenThen& rh );
1306  WhenThen& operator=( const WhenThen& rh );
1307  };
1309 
1310  class CORE_EXPORT NodeCondition : public Node
1311  {
1312  public:
1313  NodeCondition( WhenThenList* conditions, Node* elseExp = nullptr )
1314  : mConditions( *conditions )
1315  , mElseExp( elseExp )
1316  { delete conditions; }
1317  NodeCondition( const WhenThenList& conditions, Node* elseExp = nullptr )
1318  : mConditions( conditions )
1319  , mElseExp( elseExp )
1320  {}
1321  ~NodeCondition() { delete mElseExp; qDeleteAll( mConditions ); }
1322 
1323  virtual NodeType nodeType() const override { return ntCondition; }
1324  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1325  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1326  virtual QString dump() const override;
1327 
1328  virtual QStringList referencedColumns() const override;
1329  virtual bool needsGeometry() const override;
1330  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1331  virtual Node* clone() const override;
1332 
1333  protected:
1334  WhenThenList mConditions;
1336  };
1337 
1339 
1342  class CORE_EXPORT Visitor
1343  {
1344  public:
1345  virtual ~Visitor() {}
1346  virtual void visit( const NodeUnaryOperator& n ) = 0;
1347  virtual void visit( const NodeBinaryOperator& n ) = 0;
1348  virtual void visit( const NodeInOperator& n ) = 0;
1349  virtual void visit( const NodeFunction& n ) = 0;
1350  virtual void visit( const NodeLiteral& n ) = 0;
1351  virtual void visit( const NodeColumnRef& n ) = 0;
1352  virtual void visit( const NodeCondition& n ) = 0;
1353  };
1354 
1356  void acceptVisitor( Visitor& v ) const;
1357 
1362  static QString helptext( QString name );
1363 
1371  static QString variableHelpText( const QString& variableName, bool showValue = true, const QVariant& value = QVariant() );
1372 
1376  static QString group( const QString& group );
1377 
1384  static QString formatPreviewString( const QVariant& value );
1385 
1386  protected:
1390  QgsExpression();
1391 
1392  void initGeomCalculator();
1393 
1396 
1397  struct HelpArg
1398  {
1399  HelpArg( const QString& arg, const QString& desc, bool descOnly = false, bool syntaxOnly = false,
1400  bool optional = false, const QString& defaultVal = QString() )
1401  : mArg( arg )
1402  , mDescription( desc )
1403  , mDescOnly( descOnly )
1404  , mSyntaxOnly( syntaxOnly )
1405  , mOptional( optional )
1406  , mDefaultVal( defaultVal )
1407  {}
1408 
1415  };
1416 
1418  {
1419  HelpExample( const QString& expression, const QString& returns, const QString& note = QString::null )
1420  : mExpression( expression )
1421  , mReturns( returns )
1422  , mNote( note )
1423  {}
1424 
1428  };
1429 
1431  {
1432  HelpVariant( const QString& name, const QString& description,
1433  const QList<HelpArg>& arguments = QList<HelpArg>(),
1434  bool variableLenArguments = false,
1435  const QList<HelpExample>& examples = QList<HelpExample>(),
1436  const QString& notes = QString::null )
1437  : mName( name )
1438  , mDescription( description )
1439  , mArguments( arguments )
1440  , mVariableLenArguments( variableLenArguments )
1441  , mExamples( examples )
1442  , mNotes( notes )
1443  {}
1444 
1451  };
1452 
1453  struct Help
1454  {
1455  Help() {}
1456 
1457  Help( const QString& name, const QString& type, const QString& description, const QList<HelpVariant>& variants )
1458  : mName( name )
1459  , mType( type )
1460  , mDescription( description )
1461  , mVariants( variants )
1462  {}
1463 
1468  };
1469 
1476  void detach();
1477 
1478  QgsExpressionPrivate* d;
1479 
1483 
1485  static void initFunctionHelp();
1487  static void initVariableHelp();
1488 
1489  friend class QgsOgcUtils;
1490 };
1491 
1492 
1494 
1495 Q_DECLARE_METATYPE( QgsExpression::Interval )
1496 Q_DECLARE_METATYPE( QgsExpression::Node* )
1497 
1498 #endif // QGSEXPRESSION_H
Class for parsing and evaluation of expressions (formerly called "search strings").
double years()
interval length in years
Function(const QString &fnname, const ParameterList &params, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QStringList &referencedColumns=QStringList(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses named parameter list.
virtual QStringList referencedColumns() const =0
Abstract virtual method which returns a list of columns required to evaluate this node...
UnaryOperator
list of unary operators
virtual bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
QVariant defaultValue() const
Returns the default value for the parameter.
virtual QStringList referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node...
Parameter(const QString &name, bool optional=false, const QVariant &defaultValue=QVariant())
Constructor for Parameter.
bool hasNamedNodes() const
Returns true if list contains any named nodes.
virtual bool handlesNull() const
Function(const QString &fnname, int params, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QStringList &referencedColumns=QStringList(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses unnamed parameters.
double months()
interval length in months
int params() const
The number of parameters this function takes.
virtual NodeType nodeType() const override
Abstract virtual that returns the type of this node.
A abstract base class for defining QgsExpression functions.
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
QString name() const
The name of the function.
virtual NodeType nodeType() const override
Abstract virtual that returns the type of this node.
NodeColumnRef(const QString &name)
static QString helptext(QString name)
Returns the help text for a specified function.
HelpArg(const QString &arg, const QString &desc, bool descOnly=false, bool syntaxOnly=false, bool optional=false, const QString &defaultVal=QString())
double weeks()
interval length in weeks
const T & at(int i) const
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:474
Q_DECL_DEPRECATED StaticFunction(const QString &fnname, int params, FcnEval fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QStringList &referencedColumns=QStringList(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Container of fields for a vector layer.
Definition: qgsfield.h:187
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
QStringList names() const
Returns a list of names for nodes.
Interval(double seconds=0)
virtual QStringList referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node...
int count() const
Returns the number of nodes in the list.
c++ helper class for defining QgsExpression functions.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
QList< HelpVariant > mVariants
QString name
Node name.
QVariant value() const
The value of the literal.
virtual NodeType nodeType() const override
Abstract virtual that returns the type of this node.
virtual void accept(Visitor &v) const override
Support the visitor pattern.
bool usesgeometry() const
Does this function use a geometry object.
virtual bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
NodeBinaryOperator(BinaryOperator op, Node *opLeft, Node *opRight)
virtual NodeType nodeType() const override
Abstract virtual that returns the type of this node.
int indexOf(const T &value, int from) const
NodeCondition(WhenThenList *conditions, Node *elseExp=nullptr)
bool isValid()
getter interval validity
HelpVariant(const QString &name, const QString &description, const QList< HelpArg > &arguments=QList< HelpArg >(), bool variableLenArguments=false, const QList< HelpExample > &examples=QList< HelpExample >(), const QString &notes=QString::null)
static bool validateParams(int fnIndex, NodeList *args, QString &error)
Tests whether the provided argument list is valid for the matching function.
int count(const T &value) const
virtual QStringList referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node...
void append(const T &value)
QgsExpressionPrivate * d
NodeList * args() const
QList< Parameter > ParameterList
List of parameters, used for function definition.
virtual void accept(Visitor &v) const override
Support the visitor pattern.
int minParams() const
The mininum number of parameters this function takes.
QString name() const
The name of the column.
QList< Node * > mList
bool isContextual() const
Returns whether the function is only available if provided by a QgsExpressionContext object...
static QHash< QString, QString > gGroups
bool isEmpty() const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
bool isEmpty() const
double minutes()
interval length in minutus
virtual QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent) override
Returns result of evaluating the function.
double hours()
interval length in hours
Represents a single parameter passed to a function.
NodeInOperator(Node *node, NodeList *list, bool notin=false)
Help(const QString &name, const QString &type, const QString &description, const QList< HelpVariant > &variants)
static QHash< QString, QString > gVariableHelpTexts
bool isField() const
Checks whether an expression consists only of a single field reference.
QList< HelpArg > mArguments
const QString helptext() const
The help text for the function.
static QList< Function * > gmFunctions
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
HelpExample(const QString &expression, const QString &returns, const QString &note=QString::null)
virtual void accept(Visitor &v) const override
Support the visitor pattern.
WhenThen(Node *whenExp, Node *thenExp)
QList< HelpExample > mExamples
StaticFunction(const QString &fnname, const ParameterList &params, FcnEvalContext fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QStringList &referencedColumns=QStringList(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using a named list of parameter values...
NodeUnaryOperator(UnaryOperator op, Node *operand)
QString toLower() const
BinaryOperator op() const
bool operator==(const Parameter &other) const
virtual void accept(Visitor &v) const override
Support the visitor pattern.
bool contains(const T &value) const
bool contains(const T &value) const
double days()
interval length in days
virtual NodeType nodeType() const override
Abstract virtual that returns the type of this node.
virtual QStringList referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node...
virtual QStringList referencedColumns() const
virtual void accept(Visitor &v) const override
Support the visitor pattern.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:475
NodeFunction(int fnIndex, NodeList *args)
General purpose distance and area calculator.
static QMap< QString, QString > gmSpecialColumnGroups
virtual bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
virtual void accept(Visitor &v) const override
Support the visitor pattern.
bool optional() const
Returns true if the parameter is optional.
static QHash< QString, Help > gFunctionHelpTexts
QString name() const
Returns the name of the parameter.
virtual NodeType nodeType() const override
Abstract virtual that returns the type of this node.
virtual bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
BinaryOperator
list of binary operators
QList< WhenThen * > WhenThenList
double seconds()
interval length in seconds
virtual QStringList aliases() const
Returns a list of possible aliases for the function.
virtual void visit(const NodeUnaryOperator &n)=0
NodeLiteral(const QVariant &value)
QString group() const
The group the function belongs to.
Support for visitor pattern - algorithms dealing with the expressions may be implemented without modi...
UnitType
Map units that qgis supports.
Definition: qgis.h:155
virtual bool needsGeometry() const =0
Abstract virtual method which returns if the geometry is required to evaluate this expression...
const ParameterList & parameters() const
Returns the list of named parameters for the function, if set.
NamedNode(const QString &name, Node *node)
Constructor for NamedNode.
bool operator==(const Function &other) const
static QStringList gmBuiltinFunctions
virtual bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
int indexOf(const QRegExp &rx, int from) const
void append(Node *node)
Takes ownership of the provided node.
virtual void accept(Visitor &v) const override
Support the visitor pattern.
void setValid(bool valid)
setter interval validity
double ANALYSIS_EXPORT min(double x, double y)
Returns the minimum of two doubles or the first argument if both are equal.
virtual NodeType nodeType() const override
Abstract virtual that returns the type of this node.
static QList< Function * > gmOwnedFunctions
List of functions owned by the expression engine.
This is the base class for vector data providers.
bool lazyEval() const
True if this function should use lazy evaluation.
Represents a vector layer which manages a vector based data sets.
int compare(const QString &other) const
virtual QStringList aliases() const override
Returns a list of possible aliases for the function.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
The QgsOgcUtils class provides various utility functions for conversion between OGC (Open Geospatial ...
Definition: qgsogcutils.h:42
NodeCondition(const WhenThenList &conditions, Node *elseExp=nullptr)
AreaUnit
Units of area.
Definition: qgsunittypes.h:49
void append(NamedNode *node)
Adds a named node.
StaticFunction(const QString &fnname, int params, FcnEvalContext fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QStringList &referencedColumns=QStringList(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using an unnamed list of parameter val...
virtual bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
QList< Node * > list()
virtual QStringList referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node...
static QMap< QString, QVariant > gmSpecialColumns