QGIS API Documentation  2.17.0-Master (8784312)
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 
805  class CORE_EXPORT Node
806  {
807  public:
808  virtual ~Node() {}
809 
815  virtual NodeType nodeType() const = 0;
816 
822  Q_DECL_DEPRECATED virtual QVariant eval( QgsExpression* parent, const QgsFeature* f );
823 
829  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context );
830 
836  Q_DECL_DEPRECATED virtual bool prepare( QgsExpression* parent, const QgsFields &fields );
837 
843  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context );
844 
850  virtual QString dump() const = 0;
851 
860  virtual Node* clone() const = 0;
861 
872  virtual QStringList referencedColumns() const = 0;
873 
882  virtual bool needsGeometry() const = 0;
883 
899  virtual void accept( Visitor& v ) const = 0;
900  };
901 
905  class CORE_EXPORT NamedNode
906  {
907  public:
908 
913  NamedNode( const QString& name, Node* node )
914  : name( name )
915  , node( node )
916  {}
917 
920 
923  };
924 
927  class CORE_EXPORT NodeList
928  {
929  public:
930  NodeList() : mHasNamedNodes( false ) {}
931  virtual ~NodeList() { qDeleteAll( mList ); }
933  void append( Node* node ) { mList.append( node ); mNameList.append( QString() ); }
934 
938  void append( NamedNode* node ) { mList.append( node->node ); mNameList.append( node->name.toLower() ); mHasNamedNodes = true; }
939 
942  int count() const { return mList.count(); }
943 
946  bool hasNamedNodes() const { return mHasNamedNodes; }
947 
948  QList<Node*> list() { return mList; }
949 
952  QStringList names() const { return mNameList; }
953 
955  NodeList* clone() const;
956 
957  virtual QString dump() const;
958 
959  protected:
962 
963  private:
964 
965  bool mHasNamedNodes;
966  };
967 
968  //TODO QGIS 3.0 - remove
972 
975  class CORE_EXPORT NodeUnaryOperator : public Node
976  {
977  public:
979  : mOp( op )
980  , mOperand( operand )
981  {}
982  ~NodeUnaryOperator() { delete mOperand; }
983 
984  UnaryOperator op() const { return mOp; }
985  Node* operand() const { return mOperand; }
986 
987  virtual NodeType nodeType() const override { return ntUnaryOperator; }
988  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
989  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
990  virtual QString dump() const override;
991 
992  virtual QStringList referencedColumns() const override { return mOperand->referencedColumns(); }
993  virtual bool needsGeometry() const override { return mOperand->needsGeometry(); }
994  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
995  virtual Node* clone() const override;
996 
997  protected:
1000  };
1001 
1004  class CORE_EXPORT NodeBinaryOperator : public Node
1005  {
1006  public:
1007  NodeBinaryOperator( BinaryOperator op, Node* opLeft, Node* opRight )
1008  : mOp( op )
1009  , mOpLeft( opLeft )
1010  , mOpRight( opRight )
1011  {}
1012  ~NodeBinaryOperator() { delete mOpLeft; delete mOpRight; }
1013 
1014  BinaryOperator op() const { return mOp; }
1015  Node* opLeft() const { return mOpLeft; }
1016  Node* opRight() const { return mOpRight; }
1017 
1018  virtual NodeType nodeType() const override { return ntBinaryOperator; }
1019  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1020  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1021  virtual QString dump() const override;
1022 
1023  virtual QStringList referencedColumns() const override { return mOpLeft->referencedColumns() + mOpRight->referencedColumns(); }
1024  virtual bool needsGeometry() const override { return mOpLeft->needsGeometry() || mOpRight->needsGeometry(); }
1025  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1026  virtual Node* clone() const override;
1027 
1028  int precedence() const;
1029  bool leftAssociative() const;
1030 
1031  protected:
1032  bool compare( double diff );
1033  int computeInt( int x, int y );
1034  double computeDouble( double x, double y );
1035 
1040  QDateTime computeDateTimeFromInterval( const QDateTime& d, QgsInterval* i );
1041 
1045  };
1046 
1049  class CORE_EXPORT NodeInOperator : public Node
1050  {
1051  public:
1052  NodeInOperator( Node* node, NodeList* list, bool notin = false )
1053  : mNode( node )
1054  , mList( list )
1055  , mNotIn( notin )
1056  {}
1057  virtual ~NodeInOperator() { delete mNode; delete mList; }
1058 
1059  Node* node() const { return mNode; }
1060  bool isNotIn() const { return mNotIn; }
1061  NodeList* list() const { return mList; }
1062 
1063  virtual NodeType nodeType() const override { return ntInOperator; }
1064  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1065  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1066  virtual QString dump() const override;
1067 
1068  virtual QStringList referencedColumns() const override { QStringList lst( mNode->referencedColumns() ); Q_FOREACH ( const Node* n, mList->list() ) lst.append( n->referencedColumns() ); return lst; }
1069  virtual bool needsGeometry() const override { bool needs = false; Q_FOREACH ( Node* n, mList->list() ) needs |= n->needsGeometry(); return needs; }
1070  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1071  virtual Node* clone() const override;
1072 
1073  protected:
1076  bool mNotIn;
1077  };
1078 
1081  class CORE_EXPORT NodeFunction : public Node
1082  {
1083  public:
1084  NodeFunction( int fnIndex, NodeList* args ) : mFnIndex( fnIndex )
1085  {
1086  const ParameterList& functionParams = Functions()[mFnIndex]->parameters();
1087  if ( !args || !args->hasNamedNodes() || functionParams.isEmpty() )
1088  {
1089  // no named parameters, or function does not support them
1090  mArgs = args;
1091  }
1092  else
1093  {
1094  mArgs = new NodeList();
1095 
1096  int idx = 0;
1097  //first loop through unnamed arguments
1098  while ( args->names().at( idx ).isEmpty() )
1099  {
1100  mArgs->append( args->list().at( idx )->clone() );
1101  idx++;
1102  }
1103 
1104  //next copy named parameters in order expected by function
1105  for ( ; idx < functionParams.count(); ++idx )
1106  {
1107  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1108  if ( nodeIdx < 0 )
1109  {
1110  //parameter not found - insert default value for parameter
1111  mArgs->append( new NodeLiteral( functionParams.at( idx ).defaultValue() ) );
1112  }
1113  else
1114  {
1115  mArgs->append( args->list().at( nodeIdx )->clone() );
1116  }
1117  }
1118 
1119  delete args;
1120  }
1121  }
1122 
1123  virtual ~NodeFunction() { delete mArgs; }
1124 
1125  int fnIndex() const { return mFnIndex; }
1126  NodeList* args() const { return mArgs; }
1127 
1128  virtual NodeType nodeType() const override { return ntFunction; }
1129  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1130  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1131  virtual QString dump() const override;
1132 
1133  virtual QStringList referencedColumns() const override;
1134  virtual bool needsGeometry() const override { bool needs = Functions()[mFnIndex]->usesgeometry(); if ( mArgs ) { Q_FOREACH ( Node* n, mArgs->list() ) needs |= n->needsGeometry(); } return needs; }
1135  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1136  virtual Node* clone() const override;
1137 
1139  static bool validateParams( int fnIndex, NodeList* args, QString& error )
1140  {
1141  if ( !args || !args->hasNamedNodes() )
1142  return true;
1143 
1144  const ParameterList& functionParams = Functions()[fnIndex]->parameters();
1145  if ( functionParams.isEmpty() )
1146  {
1147  error = QString( "%1 does not supported named parameters" ).arg( Functions()[fnIndex]->name() );
1148  return false;
1149  }
1150  else
1151  {
1152  QSet< int > providedArgs;
1153  QSet< int > handledArgs;
1154  int idx = 0;
1155  //first loop through unnamed arguments
1156  while ( args->names().at( idx ).isEmpty() )
1157  {
1158  providedArgs << idx;
1159  handledArgs << idx;
1160  idx++;
1161  }
1162 
1163  //next check named parameters
1164  for ( ; idx < functionParams.count(); ++idx )
1165  {
1166  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1167  if ( nodeIdx < 0 )
1168  {
1169  if ( !functionParams.at( idx ).optional() )
1170  {
1171  error = QString( "No value specified for parameter '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
1172  return false;
1173  }
1174  }
1175  else
1176  {
1177  if ( providedArgs.contains( idx ) )
1178  {
1179  error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
1180  return false;
1181  }
1182  }
1183  providedArgs << idx;
1184  handledArgs << nodeIdx;
1185  }
1186 
1187  //last check for bad names
1188  idx = 0;
1189  Q_FOREACH ( const QString& name, args->names() )
1190  {
1191  if ( !name.isEmpty() && !functionParams.contains( name ) )
1192  {
1193  error = QString( "Invalid parameter name '%1' for %2" ).arg( name, Functions()[fnIndex]->name() );
1194  return false;
1195  }
1196  if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1197  {
1198  int functionIdx = functionParams.indexOf( name );
1199  if ( providedArgs.contains( functionIdx ) )
1200  {
1201  error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(), Functions()[fnIndex]->name() );
1202  return false;
1203  }
1204  }
1205  idx++;
1206  }
1207 
1208  }
1209  return true;
1210  }
1211 
1212  protected:
1215 
1216  };
1217 
1220  class CORE_EXPORT NodeLiteral : public Node
1221  {
1222  public:
1223  NodeLiteral( const QVariant& value )
1224  : mValue( value )
1225  {}
1226 
1228  inline QVariant value() const { return mValue; }
1229 
1230  virtual NodeType nodeType() const override { return ntLiteral; }
1231  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1232  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1233  virtual QString dump() const override;
1234 
1235  virtual QStringList referencedColumns() const override { return QStringList(); }
1236  virtual bool needsGeometry() const override { return false; }
1237  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1238  virtual Node* clone() const override;
1239 
1240  protected:
1242  };
1243 
1246  class CORE_EXPORT NodeColumnRef : public Node
1247  {
1248  public:
1249  NodeColumnRef( const QString& name )
1250  : mName( name )
1251  , mIndex( -1 )
1252  {}
1253 
1255  QString name() const { return mName; }
1256 
1257  virtual NodeType nodeType() const override { return ntColumnRef; }
1258  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1259  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1260  virtual QString dump() const override;
1261 
1262  virtual QStringList referencedColumns() const override { return QStringList( mName ); }
1263  virtual bool needsGeometry() const override { return false; }
1264 
1265  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1266  virtual Node* clone() const override;
1267 
1268  protected:
1270  int mIndex;
1271  };
1272 
1275  class CORE_EXPORT WhenThen
1276  {
1277  public:
1278  WhenThen( Node* whenExp, Node* thenExp )
1279  : mWhenExp( whenExp )
1280  , mThenExp( thenExp )
1281  {}
1282  ~WhenThen() { delete mWhenExp; delete mThenExp; }
1283 
1284  // protected:
1287 
1288  private:
1289  WhenThen( const WhenThen& rh );
1290  WhenThen& operator=( const WhenThen& rh );
1291  };
1293 
1296  class CORE_EXPORT NodeCondition : public Node
1297  {
1298  public:
1299  NodeCondition( WhenThenList* conditions, Node* elseExp = nullptr )
1300  : mConditions( *conditions )
1301  , mElseExp( elseExp )
1302  { delete conditions; }
1303  NodeCondition( const WhenThenList& conditions, Node* elseExp = nullptr )
1304  : mConditions( conditions )
1305  , mElseExp( elseExp )
1306  {}
1307  ~NodeCondition() { delete mElseExp; qDeleteAll( mConditions ); }
1308 
1309  virtual NodeType nodeType() const override { return ntCondition; }
1310  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1311  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1312  virtual QString dump() const override;
1313 
1314  virtual QStringList referencedColumns() const override;
1315  virtual bool needsGeometry() const override;
1316  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1317  virtual Node* clone() const override;
1318 
1319  protected:
1320  WhenThenList mConditions;
1322  };
1323 
1325 
1329  class CORE_EXPORT Visitor
1330  {
1331  public:
1332  virtual ~Visitor() {}
1333  virtual void visit( const NodeUnaryOperator& n ) = 0;
1334  virtual void visit( const NodeBinaryOperator& n ) = 0;
1335  virtual void visit( const NodeInOperator& n ) = 0;
1336  virtual void visit( const NodeFunction& n ) = 0;
1337  virtual void visit( const NodeLiteral& n ) = 0;
1338  virtual void visit( const NodeColumnRef& n ) = 0;
1339  virtual void visit( const NodeCondition& n ) = 0;
1340  };
1341 
1343  void acceptVisitor( Visitor& v ) const;
1344 
1349  static QString helptext( QString name );
1350 
1358  static QString variableHelpText( const QString& variableName, bool showValue = true, const QVariant& value = QVariant() );
1359 
1363  static QString group( const QString& group );
1364 
1371  static QString formatPreviewString( const QVariant& value );
1372 
1373  protected:
1377  QgsExpression();
1378 
1379  void initGeomCalculator();
1380 
1383 
1384  struct HelpArg
1385  {
1386  HelpArg( const QString& arg, const QString& desc, bool descOnly = false, bool syntaxOnly = false,
1387  bool optional = false, const QString& defaultVal = QString() )
1388  : mArg( arg )
1389  , mDescription( desc )
1390  , mDescOnly( descOnly )
1391  , mSyntaxOnly( syntaxOnly )
1392  , mOptional( optional )
1393  , mDefaultVal( defaultVal )
1394  {}
1395 
1402  };
1403 
1405  {
1406  HelpExample( const QString& expression, const QString& returns, const QString& note = QString::null )
1407  : mExpression( expression )
1408  , mReturns( returns )
1409  , mNote( note )
1410  {}
1411 
1415  };
1416 
1418  {
1419  HelpVariant( const QString& name, const QString& description,
1420  const QList<HelpArg>& arguments = QList<HelpArg>(),
1421  bool variableLenArguments = false,
1422  const QList<HelpExample>& examples = QList<HelpExample>(),
1423  const QString& notes = QString::null )
1424  : mName( name )
1425  , mDescription( description )
1426  , mArguments( arguments )
1427  , mVariableLenArguments( variableLenArguments )
1428  , mExamples( examples )
1429  , mNotes( notes )
1430  {}
1431 
1438  };
1439 
1440  struct Help
1441  {
1442  Help() {}
1443 
1444  Help( const QString& name, const QString& type, const QString& description, const QList<HelpVariant>& variants )
1445  : mName( name )
1446  , mType( type )
1447  , mDescription( description )
1448  , mVariants( variants )
1449  {}
1450 
1455  };
1456 
1463  void detach();
1464 
1465  QgsExpressionPrivate* d;
1466 
1470 
1472  static void initFunctionHelp();
1474  static void initVariableHelp();
1475 
1476  friend class QgsOgcUtils;
1477 };
1478 
1479 
1481 
1483 
1484 #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
QgsInterval Interval
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:515
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.
Q_DECLARE_METATYPE(QModelIndex)
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:516
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
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