QGIS API Documentation  2.15.0-Master (94d88e6)
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 #include "qgsinterval.h"
30 
31 class QgsFeature;
32 class QgsGeometry;
33 class QgsOgcUtils;
34 class QgsVectorLayer;
36 class QgsField;
37 class QgsFields;
38 class QgsDistanceArea;
39 class QDomElement;
41 class QgsExpressionPrivate;
42 
109 class CORE_EXPORT QgsExpression
110 {
111  Q_DECLARE_TR_FUNCTIONS( QgsExpression )
112  public:
119  QgsExpression( const QString& expr );
120 
126  QgsExpression( const QgsExpression& other );
132  QgsExpression& operator=( const QgsExpression& other );
133  ~QgsExpression();
134 
136  bool hasParserError() const;
138  QString parserErrorString() const;
139 
140  class Node;
141 
143  const Node* rootNode() const;
144 
147  Q_DECL_DEPRECATED bool prepare( const QgsFields &fields );
148 
153  bool prepare( const QgsExpressionContext *context );
154 
163  QStringList referencedColumns() const;
164 
166  bool needsGeometry() const;
167 
168  // evaluation
169 
173  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature* f );
174 
179  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature& f );
180 
184  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature* f, const QgsFields& fields );
185 
190  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature& f, const QgsFields& fields );
191 
196  QVariant evaluate();
197 
203  QVariant evaluate( const QgsExpressionContext* context );
204 
206  bool hasEvalError() const;
208  QString evalErrorString() const;
210  void setEvalErrorString( const QString& str );
211 
214  Q_DECL_DEPRECATED void setCurrentRowNumber( int rowNumber );
217  Q_DECL_DEPRECATED int currentRowNumber(); //TODO QGIS 3.0: make the following methods private. They are still required for replaceExpressionText
218  //but should not be publicly used
222  Q_DECL_DEPRECATED static void setSpecialColumn( const QString& name, const QVariant& value );
226  Q_DECL_DEPRECATED static void unsetSpecialColumn( const QString& name );
230  Q_DECL_DEPRECATED static QVariant specialColumn( const QString& name );
231 
235  static bool hasSpecialColumn( const QString& name );
236 
240  bool isField() const { return rootNode() && dynamic_cast<const NodeColumnRef*>( rootNode() ) ;}
241 
243  Q_DECL_DEPRECATED static bool isValid( const QString& text, const QgsFields& fields, QString &errorMessage );
244 
252  static bool isValid( const QString& text, const QgsExpressionContext* context, QString &errorMessage );
253 
254  void setScale( double scale );
255 
256  double scale();
257 
261  QString expression() const;
262 
267  QString dump() const;
268 
275  QgsDistanceArea *geomCalculator();
276 
283  //TODO QGIS 3.0 change calc to a pointer, so that calculator can be cleared by passing nullptr
284  void setGeomCalculator( const QgsDistanceArea &calc );
285 
292  QGis::UnitType distanceUnits() const;
293 
300  void setDistanceUnits( QGis::UnitType unit );
301 
308  QgsUnitTypes::AreaUnit areaUnits() const;
309 
316  void setAreaUnits( QgsUnitTypes::AreaUnit unit );
317 
331  Q_DECL_DEPRECATED static QString replaceExpressionText( const QString &action, const QgsFeature *feat,
332  QgsVectorLayer *layer,
333  const QMap<QString, QVariant> *substitutionMap = nullptr,
334  const QgsDistanceArea* distanceArea = nullptr );
335 
347  static QString replaceExpressionText( const QString &action, const QgsExpressionContext* context,
348  const QMap<QString, QVariant> *substitutionMap = nullptr,
349  const QgsDistanceArea* distanceArea = nullptr );
350 
360  static double evaluateToDouble( const QString& text, const double fallbackValue );
361 
367  {
370  };
371 
377  {
378  // logical
381 
382  // comparison
383  boEQ, // =
384  boNE, // <>
385  boLE, // <=
386  boGE, // >=
387  boLT, // <
388  boGT, // >
396 
397  // math
405 
406  // strings
408  };
409 
411  {
421  };
422 
424  static const char* BinaryOperatorText[];
425 
427  static const char* UnaryOperatorText[];
428 
433  class CORE_EXPORT Parameter
434  {
435  public:
436 
442  Parameter( const QString& name,
443  bool optional = false,
444  const QVariant& defaultValue = QVariant() )
445  : mName( name )
446  , mOptional( optional )
447  , mDefaultValue( defaultValue )
448  {}
449 
451  QString name() const { return mName; }
452 
454  bool optional() const { return mOptional; }
455 
457  QVariant defaultValue() const { return mDefaultValue; }
458 
459  bool operator==( const Parameter& other ) const
460  {
461  return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
462  }
463 
464  private:
465  QString mName;
466  bool mOptional;
467  QVariant mDefaultValue;
468  };
469 
472 
474  typedef QVariant( *FcnEval )( const QVariantList& values, const QgsFeature* f, QgsExpression* parent );
475 
478  typedef QVariant( *FcnEvalContext )( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent );
479 
483  class CORE_EXPORT Function
484  {
485  public:
486 
488  Function( const QString& fnname,
489  int params,
490  const QString& group,
491  const QString& helpText = QString(),
492  bool usesGeometry = false,
493  const QStringList& referencedColumns = QStringList(),
494  bool lazyEval = false,
495  bool handlesNull = false,
496  bool isContextual = false )
497  : mName( fnname )
498  , mParams( params )
499  , mUsesGeometry( usesGeometry )
500  , mGroup( group )
501  , mHelpText( helpText )
502  , mReferencedColumns( referencedColumns )
503  , mLazyEval( lazyEval )
504  , mHandlesNull( handlesNull )
505  , mIsContextual( isContextual )
506  {
507  }
508 
512  Function( const QString& fnname,
513  const ParameterList& params,
514  const QString& group,
515  const QString& helpText = QString(),
516  bool usesGeometry = false,
517  const QStringList& referencedColumns = QStringList(),
518  bool lazyEval = false,
519  bool handlesNull = false,
520  bool isContextual = false )
521  : mName( fnname )
522  , mParams( 0 )
523  , mParameterList( params )
524  , mUsesGeometry( usesGeometry )
525  , mGroup( group )
526  , mHelpText( helpText )
527  , mReferencedColumns( referencedColumns )
528  , mLazyEval( lazyEval )
529  , mHandlesNull( handlesNull )
530  , mIsContextual( isContextual )
531  {}
532 
533  virtual ~Function() {}
534 
536  QString name() const { return mName; }
537 
539  int params() const { return mParameterList.isEmpty() ? mParams : mParameterList.count(); }
540 
542  int minParams() const
543  {
544  if ( mParameterList.isEmpty() )
545  return mParams;
546 
547  int min = 0;
548  Q_FOREACH ( const Parameter& param, mParameterList )
549  {
550  if ( !param.optional() )
551  min++;
552  }
553  return min;
554  }
555 
559  const ParameterList& parameters() const { return mParameterList; }
560 
562  //TODO QGIS 3.0 - rename to usesGeometry()
563  bool usesgeometry() const { return mUsesGeometry; }
564 
570  virtual QStringList aliases() const { return QStringList(); }
571 
575  bool lazyEval() const { return mLazyEval; }
576 
577  virtual QStringList referencedColumns() const { return mReferencedColumns; }
578 
582  bool isContextual() const { return mIsContextual; }
583 
585  QString group() const { return mGroup; }
587  //TODO QGIS 3.0 - rename to helpText()
588  const QString helptext() const { return mHelpText.isEmpty() ? QgsExpression::helptext( mName ) : mHelpText; }
589 
591  Q_DECL_DEPRECATED virtual QVariant func( const QVariantList&, const QgsFeature*, QgsExpression* );
592 
600  //TODO QGIS 3.0 - rename python method
601  virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent );
602 
603  bool operator==( const Function& other ) const
604  {
605  if ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 )
606  return true;
607 
608  return false;
609  }
610 
611  virtual bool handlesNull() const { return mHandlesNull; }
612 
613  private:
614  QString mName;
615  int mParams;
616  ParameterList mParameterList;
617  bool mUsesGeometry;
618  QString mGroup;
619  QString mHelpText;
620  QStringList mReferencedColumns;
621  bool mLazyEval;
622  bool mHandlesNull;
623  bool mIsContextual; //if true function is only available through an expression context
624  };
625 
630  class StaticFunction : public Function
631  {
632  public:
634  Q_DECL_DEPRECATED StaticFunction( const QString& fnname,
635  int params,
636  FcnEval fcn,
637  const QString& group,
638  const QString& helpText = QString(),
639  bool usesGeometry = false,
640  const QStringList& referencedColumns = QStringList(),
641  bool lazyEval = false,
642  const QStringList& aliases = QStringList(),
643  bool handlesNull = false )
644  : Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval, handlesNull )
645  , mFnc( fcn )
646  , mContextFnc( nullptr )
647  , mAliases( aliases )
648  {}
649 
650  virtual ~StaticFunction() {}
651 
654  StaticFunction( const QString& fnname,
655  int params,
656  FcnEvalContext fcn,
657  const QString& group,
658  const QString& helpText = QString(),
659  bool usesGeometry = false,
660  const QStringList& referencedColumns = QStringList(),
661  bool lazyEval = false,
662  const QStringList& aliases = QStringList(),
663  bool handlesNull = false )
664  : Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval, handlesNull )
665  , mFnc( nullptr )
666  , mContextFnc( fcn )
667  , mAliases( aliases )
668  {}
669 
672  StaticFunction( const QString& fnname,
673  const ParameterList& params,
674  FcnEvalContext fcn,
675  const QString& group,
676  const QString& helpText = QString(),
677  bool usesGeometry = false,
678  const QStringList& referencedColumns = QStringList(),
679  bool lazyEval = false,
680  const QStringList& aliases = QStringList(),
681  bool handlesNull = false )
682  : Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval, handlesNull )
683  , mFnc( nullptr )
684  , mContextFnc( fcn )
685  , mAliases( aliases )
686  {}
687 
689  Q_DECL_DEPRECATED virtual QVariant func( const QVariantList& values, const QgsFeature* f, QgsExpression* parent ) override;
690 
697  virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent ) override
698  {
699  return mContextFnc ? mContextFnc( values, context, parent ) : QVariant();
700  }
701 
702  virtual QStringList aliases() const override { return mAliases; }
703 
704  private:
705  FcnEval mFnc;
706  FcnEvalContext mContextFnc;
707  QStringList mAliases;
708  };
709 
712  static const QList<Function*>& Functions();
713 
716  static const QStringList& BuiltinFunctions();
717 
724  static bool registerFunction( Function* function, bool transferOwnership = false );
725 
730  static bool unregisterFunction( const QString& name );
731 
735 
739  static void cleanRegisteredFunctions();
740 
742  static bool isFunctionName( const QString& name );
743 
745  static int functionIndex( const QString& name );
746 
750  static int functionCount();
751 
755  static QList<Function*> specialColumns();
756 
761  static QString quotedColumnRef( QString name );
762 
767  static QString quotedString( QString text );
768 
776  static QString quotedValue( const QVariant& value );
777 
786  static QString quotedValue( const QVariant& value, QVariant::Type type );
787 
789 
790  class Visitor; // visitor interface is defined below
791 
792  enum NodeType
793  {
800  ntCondition
801  };
802 
803  class CORE_EXPORT Node
804  {
805  public:
806  virtual ~Node() {}
807 
813  virtual NodeType nodeType() const = 0;
814 
820  Q_DECL_DEPRECATED virtual QVariant eval( QgsExpression* parent, const QgsFeature* f );
821 
827  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context );
828 
834  Q_DECL_DEPRECATED virtual bool prepare( QgsExpression* parent, const QgsFields &fields );
835 
841  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context );
842 
848  virtual QString dump() const = 0;
849 
858  virtual Node* clone() const = 0;
859 
870  virtual QStringList referencedColumns() const = 0;
871 
880  virtual bool needsGeometry() const = 0;
881 
897  virtual void accept( Visitor& v ) const = 0;
898  };
899 
902  class CORE_EXPORT NamedNode
903  {
904  public:
905 
910  NamedNode( const QString& name, Node* node )
911  : name( name )
912  , node( node )
913  {}
914 
917 
920  };
921 
922  class CORE_EXPORT NodeList
923  {
924  public:
925  NodeList() : mHasNamedNodes( false ) {}
926  virtual ~NodeList() { qDeleteAll( mList ); }
928  void append( Node* node ) { mList.append( node ); mNameList.append( QString() ); }
929 
933  void append( NamedNode* node ) { mList.append( node->node ); mNameList.append( node->name.toLower() ); mHasNamedNodes = true; }
934 
937  int count() const { return mList.count(); }
938 
941  bool hasNamedNodes() const { return mHasNamedNodes; }
942 
943  QList<Node*> list() { return mList; }
944 
947  QStringList names() const { return mNameList; }
948 
950  NodeList* clone() const;
951 
952  virtual QString dump() const;
953 
954  protected:
957 
958  private:
959 
960  bool mHasNamedNodes;
961  };
962 
963  //TODO QGIS 3.0 - remove
966 
967  class CORE_EXPORT NodeUnaryOperator : public Node
968  {
969  public:
971  : mOp( op )
972  , mOperand( operand )
973  {}
974  ~NodeUnaryOperator() { delete mOperand; }
975 
976  UnaryOperator op() const { return mOp; }
977  Node* operand() const { return mOperand; }
978 
979  virtual NodeType nodeType() const override { return ntUnaryOperator; }
980  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
981  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
982  virtual QString dump() const override;
983 
984  virtual QStringList referencedColumns() const override { return mOperand->referencedColumns(); }
985  virtual bool needsGeometry() const override { return mOperand->needsGeometry(); }
986  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
987  virtual Node* clone() const override;
988 
989  protected:
992  };
993 
994  class CORE_EXPORT NodeBinaryOperator : public Node
995  {
996  public:
997  NodeBinaryOperator( BinaryOperator op, Node* opLeft, Node* opRight )
998  : mOp( op )
999  , mOpLeft( opLeft )
1000  , mOpRight( opRight )
1001  {}
1002  ~NodeBinaryOperator() { delete mOpLeft; delete mOpRight; }
1003 
1004  BinaryOperator op() const { return mOp; }
1005  Node* opLeft() const { return mOpLeft; }
1006  Node* opRight() const { return mOpRight; }
1007 
1008  virtual NodeType nodeType() const override { return ntBinaryOperator; }
1009  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1010  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1011  virtual QString dump() const override;
1012 
1013  virtual QStringList referencedColumns() const override { return mOpLeft->referencedColumns() + mOpRight->referencedColumns(); }
1014  virtual bool needsGeometry() const override { return mOpLeft->needsGeometry() || mOpRight->needsGeometry(); }
1015  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1016  virtual Node* clone() const override;
1017 
1018  int precedence() const;
1019  bool leftAssociative() const;
1020 
1021  protected:
1022  bool compare( double diff );
1023  int computeInt( int x, int y );
1024  double computeDouble( double x, double y );
1025 
1030  QDateTime computeDateTimeFromInterval( const QDateTime& d, QgsInterval* i );
1031 
1035  };
1036 
1037  class CORE_EXPORT NodeInOperator : public Node
1038  {
1039  public:
1040  NodeInOperator( Node* node, NodeList* list, bool notin = false )
1041  : mNode( node )
1042  , mList( list )
1043  , mNotIn( notin )
1044  {}
1045  virtual ~NodeInOperator() { delete mNode; delete mList; }
1046 
1047  Node* node() const { return mNode; }
1048  bool isNotIn() const { return mNotIn; }
1049  NodeList* list() const { return mList; }
1050 
1051  virtual NodeType nodeType() const override { return ntInOperator; }
1052  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1053  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1054  virtual QString dump() const override;
1055 
1056  virtual QStringList referencedColumns() const override { QStringList lst( mNode->referencedColumns() ); Q_FOREACH ( const Node* n, mList->list() ) lst.append( n->referencedColumns() ); return lst; }
1057  virtual bool needsGeometry() const override { bool needs = false; Q_FOREACH ( Node* n, mList->list() ) needs |= n->needsGeometry(); return needs; }
1058  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1059  virtual Node* clone() const override;
1060 
1061  protected:
1064  bool mNotIn;
1065  };
1066 
1067  class CORE_EXPORT NodeFunction : public Node
1068  {
1069  public:
1070  NodeFunction( int fnIndex, NodeList* args ) : mFnIndex( fnIndex )
1071  {
1072  const ParameterList& functionParams = Functions()[mFnIndex]->parameters();
1073  if ( !args || !args->hasNamedNodes() || functionParams.isEmpty() )
1074  {
1075  // no named parameters, or function does not support them
1076  mArgs = args;
1077  }
1078  else
1079  {
1080  mArgs = new NodeList();
1081 
1082  int idx = 0;
1083  //first loop through unnamed arguments
1084  while ( args->names().at( idx ).isEmpty() )
1085  {
1086  mArgs->append( args->list().at( idx )->clone() );
1087  idx++;
1088  }
1089 
1090  //next copy named parameters in order expected by function
1091  for ( ; idx < functionParams.count(); ++idx )
1092  {
1093  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1094  if ( nodeIdx < 0 )
1095  {
1096  //parameter not found - insert default value for parameter
1097  mArgs->append( new NodeLiteral( functionParams.at( idx ).defaultValue() ) );
1098  }
1099  else
1100  {
1101  mArgs->append( args->list().at( nodeIdx )->clone() );
1102  }
1103  }
1104 
1105  delete args;
1106  }
1107  }
1108 
1109  virtual ~NodeFunction() { delete mArgs; }
1110 
1111  int fnIndex() const { return mFnIndex; }
1112  NodeList* args() const { return mArgs; }
1113 
1114  virtual NodeType nodeType() const override { return ntFunction; }
1115  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1116  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1117  virtual QString dump() const override;
1118 
1119  virtual QStringList referencedColumns() const override;
1120  virtual bool needsGeometry() const override { bool needs = Functions()[mFnIndex]->usesgeometry(); if ( mArgs ) { Q_FOREACH ( Node* n, mArgs->list() ) needs |= n->needsGeometry(); } return needs; }
1121  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1122  virtual Node* clone() const override;
1123 
1125  static bool validateParams( int fnIndex, NodeList* args, QString& error )
1126  {
1127  if ( !args || !args->hasNamedNodes() )
1128  return true;
1129 
1130  const ParameterList& functionParams = Functions()[fnIndex]->parameters();
1131  if ( functionParams.isEmpty() )
1132  {
1133  error = QString( "%1 does not supported named parameters" ).arg( Functions()[fnIndex]->name() );
1134  return false;
1135  }
1136  else
1137  {
1138  QSet< int > providedArgs;
1139  QSet< int > handledArgs;
1140  int idx = 0;
1141  //first loop through unnamed arguments
1142  while ( args->names().at( idx ).isEmpty() )
1143  {
1144  providedArgs << idx;
1145  handledArgs << idx;
1146  idx++;
1147  }
1148 
1149  //next check named parameters
1150  for ( ; idx < functionParams.count(); ++idx )
1151  {
1152  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1153  if ( nodeIdx < 0 )
1154  {
1155  if ( !functionParams.at( idx ).optional() )
1156  {
1157  error = QString( "No value specified for parameter '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
1158  return false;
1159  }
1160  }
1161  else
1162  {
1163  if ( providedArgs.contains( idx ) )
1164  {
1165  error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
1166  return false;
1167  }
1168  }
1169  providedArgs << idx;
1170  handledArgs << nodeIdx;
1171  }
1172 
1173  //last check for bad names
1174  idx = 0;
1175  Q_FOREACH ( const QString& name, args->names() )
1176  {
1177  if ( !name.isEmpty() && !functionParams.contains( name ) )
1178  {
1179  error = QString( "Invalid parameter name '%1' for %2" ).arg( name, 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 = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(), Functions()[fnIndex]->name() );
1188  return false;
1189  }
1190  }
1191  idx++;
1192  }
1193 
1194  }
1195  return true;
1196  }
1197 
1198  protected:
1201 
1202  };
1203 
1204  class CORE_EXPORT NodeLiteral : public Node
1205  {
1206  public:
1207  NodeLiteral( const QVariant& value )
1208  : mValue( value )
1209  {}
1210 
1212  inline QVariant value() const { return mValue; }
1213 
1214  virtual NodeType nodeType() const override { return ntLiteral; }
1215  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1216  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1217  virtual QString dump() const override;
1218 
1219  virtual QStringList referencedColumns() const override { return QStringList(); }
1220  virtual bool needsGeometry() const override { return false; }
1221  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1222  virtual Node* clone() const override;
1223 
1224  protected:
1226  };
1227 
1228  class CORE_EXPORT NodeColumnRef : public Node
1229  {
1230  public:
1231  NodeColumnRef( const QString& name )
1232  : mName( name )
1233  , mIndex( -1 )
1234  {}
1235 
1237  QString name() const { return mName; }
1238 
1239  virtual NodeType nodeType() const override { return ntColumnRef; }
1240  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1241  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1242  virtual QString dump() const override;
1243 
1244  virtual QStringList referencedColumns() const override { return QStringList( mName ); }
1245  virtual bool needsGeometry() const override { return false; }
1246 
1247  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1248  virtual Node* clone() const override;
1249 
1250  protected:
1252  int mIndex;
1253  };
1254 
1255  class CORE_EXPORT WhenThen
1256  {
1257  public:
1258  WhenThen( Node* whenExp, Node* thenExp )
1259  : mWhenExp( whenExp )
1260  , mThenExp( thenExp )
1261  {}
1262  ~WhenThen() { delete mWhenExp; delete mThenExp; }
1263 
1264  // protected:
1267 
1268  private:
1269  WhenThen( const WhenThen& rh );
1270  WhenThen& operator=( const WhenThen& rh );
1271  };
1273 
1274  class CORE_EXPORT NodeCondition : public Node
1275  {
1276  public:
1277  NodeCondition( WhenThenList* conditions, Node* elseExp = nullptr )
1278  : mConditions( *conditions )
1279  , mElseExp( elseExp )
1280  { delete conditions; }
1281  NodeCondition( const WhenThenList& conditions, Node* elseExp = nullptr )
1282  : mConditions( conditions )
1283  , mElseExp( elseExp )
1284  {}
1285  ~NodeCondition() { delete mElseExp; qDeleteAll( mConditions ); }
1286 
1287  virtual NodeType nodeType() const override { return ntCondition; }
1288  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1289  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1290  virtual QString dump() const override;
1291 
1292  virtual QStringList referencedColumns() const override;
1293  virtual bool needsGeometry() const override;
1294  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1295  virtual Node* clone() const override;
1296 
1297  protected:
1298  WhenThenList mConditions;
1300  };
1301 
1303 
1306  class CORE_EXPORT Visitor
1307  {
1308  public:
1309  virtual ~Visitor() {}
1310  virtual void visit( const NodeUnaryOperator& n ) = 0;
1311  virtual void visit( const NodeBinaryOperator& n ) = 0;
1312  virtual void visit( const NodeInOperator& n ) = 0;
1313  virtual void visit( const NodeFunction& n ) = 0;
1314  virtual void visit( const NodeLiteral& n ) = 0;
1315  virtual void visit( const NodeColumnRef& n ) = 0;
1316  virtual void visit( const NodeCondition& n ) = 0;
1317  };
1318 
1320  void acceptVisitor( Visitor& v ) const;
1321 
1326  static QString helptext( QString name );
1327 
1335  static QString variableHelpText( const QString& variableName, bool showValue = true, const QVariant& value = QVariant() );
1336 
1340  static QString group( const QString& group );
1341 
1348  static QString formatPreviewString( const QVariant& value );
1349 
1350  protected:
1354  QgsExpression();
1355 
1356  void initGeomCalculator();
1357 
1360 
1361  struct HelpArg
1362  {
1363  HelpArg( const QString& arg, const QString& desc, bool descOnly = false, bool syntaxOnly = false,
1364  bool optional = false, const QString& defaultVal = QString() )
1365  : mArg( arg )
1366  , mDescription( desc )
1367  , mDescOnly( descOnly )
1368  , mSyntaxOnly( syntaxOnly )
1369  , mOptional( optional )
1370  , mDefaultVal( defaultVal )
1371  {}
1372 
1379  };
1380 
1382  {
1383  HelpExample( const QString& expression, const QString& returns, const QString& note = QString::null )
1384  : mExpression( expression )
1385  , mReturns( returns )
1386  , mNote( note )
1387  {}
1388 
1392  };
1393 
1395  {
1396  HelpVariant( const QString& name, const QString& description,
1397  const QList<HelpArg>& arguments = QList<HelpArg>(),
1398  bool variableLenArguments = false,
1399  const QList<HelpExample>& examples = QList<HelpExample>(),
1400  const QString& notes = QString::null )
1401  : mName( name )
1402  , mDescription( description )
1403  , mArguments( arguments )
1404  , mVariableLenArguments( variableLenArguments )
1405  , mExamples( examples )
1406  , mNotes( notes )
1407  {}
1408 
1415  };
1416 
1417  struct Help
1418  {
1419  Help() {}
1420 
1421  Help( const QString& name, const QString& type, const QString& description, const QList<HelpVariant>& variants )
1422  : mName( name )
1423  , mType( type )
1424  , mDescription( description )
1425  , mVariants( variants )
1426  {}
1427 
1432  };
1433 
1440  void detach();
1441 
1442  QgsExpressionPrivate* d;
1443 
1447 
1449  static void initFunctionHelp();
1451  static void initVariableHelp();
1452 
1453  friend class QgsOgcUtils;
1454 };
1455 
1456 
1458 
1459 Q_DECLARE_METATYPE( QgsExpression::Node* )
1460 
1461 #endif // QGSEXPRESSION_H
Class for parsing and evaluation of expressions (formerly called "search strings").
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.
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.
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())
const T & at(int i) const
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:504
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:193
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
QStringList names() const
Returns a list of names for nodes.
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)
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
virtual QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent) override
Returns result of evaluating the function.
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
A representation of the interval between two datetime values.
Definition: qgsinterval.h:34
bool contains(const T &value) const
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:505
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.
QgsInterval Interval
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
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:159
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.
UnaryOperator op() const
virtual void accept(Visitor &v) const override
Support the visitor pattern.
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:43
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