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 ) : mSeconds( seconds ), mValid( true ) { }
974 
976  double years() { return mSeconds / YEARS;}
978  double months() { return mSeconds / MONTHS; }
980  double weeks() { return mSeconds / WEEKS;}
982  double days() { return mSeconds / DAY;}
984  double hours() { return mSeconds / HOUR;}
986  double minutes() { return mSeconds / MINUTE;}
988  double seconds() { return mSeconds; }
990  bool isValid() { return mValid; }
992  void setValid( bool valid ) { mValid = valid; }
994  bool operator==( QgsExpression::Interval other ) const;
996  static QgsExpression::Interval invalidInterVal();
998  static QgsExpression::Interval fromString( const QString& string );
999 
1000  private:
1001  double mSeconds;
1002  bool mValid;
1003  };
1004 
1005  class CORE_EXPORT NodeUnaryOperator : public Node
1006  {
1007  public:
1008  NodeUnaryOperator( UnaryOperator op, Node* operand ) : mOp( op ), mOperand( operand ) {}
1009  ~NodeUnaryOperator() { delete mOperand; }
1010 
1011  UnaryOperator op() const { return mOp; }
1012  Node* operand() const { return mOperand; }
1013 
1014  virtual NodeType nodeType() const override { return ntUnaryOperator; }
1015  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1016  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1017  virtual QString dump() const override;
1018 
1019  virtual QStringList referencedColumns() const override { return mOperand->referencedColumns(); }
1020  virtual bool needsGeometry() const override { return mOperand->needsGeometry(); }
1021  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1022  virtual Node* clone() const override;
1023 
1024  protected:
1027  };
1028 
1029  class CORE_EXPORT NodeBinaryOperator : public Node
1030  {
1031  public:
1032  NodeBinaryOperator( BinaryOperator op, Node* opLeft, Node* opRight ) : mOp( op ), mOpLeft( opLeft ), mOpRight( opRight ) {}
1033  ~NodeBinaryOperator() { delete mOpLeft; delete mOpRight; }
1034 
1035  BinaryOperator op() const { return mOp; }
1036  Node* opLeft() const { return mOpLeft; }
1037  Node* opRight() const { return mOpRight; }
1038 
1039  virtual NodeType nodeType() const override { return ntBinaryOperator; }
1040  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1041  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1042  virtual QString dump() const override;
1043 
1044  virtual QStringList referencedColumns() const override { return mOpLeft->referencedColumns() + mOpRight->referencedColumns(); }
1045  virtual bool needsGeometry() const override { return mOpLeft->needsGeometry() || mOpRight->needsGeometry(); }
1046  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1047  virtual Node* clone() const override;
1048 
1049  int precedence() const;
1050  bool leftAssociative() const;
1051 
1052  protected:
1053  bool compare( double diff );
1054  int computeInt( int x, int y );
1055  double computeDouble( double x, double y );
1056  QDateTime computeDateTimeFromInterval( const QDateTime& d, QgsExpression::Interval *i );
1057 
1061  };
1062 
1063  class CORE_EXPORT NodeInOperator : public Node
1064  {
1065  public:
1066  NodeInOperator( Node* node, NodeList* list, bool notin = false ) : mNode( node ), mList( list ), mNotIn( notin ) {}
1067  virtual ~NodeInOperator() { delete mNode; delete mList; }
1068 
1069  Node* node() const { return mNode; }
1070  bool isNotIn() const { return mNotIn; }
1071  NodeList* list() const { return mList; }
1072 
1073  virtual NodeType nodeType() const override { return ntInOperator; }
1074  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1075  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1076  virtual QString dump() const override;
1077 
1078  virtual QStringList referencedColumns() const override { QStringList lst( mNode->referencedColumns() ); Q_FOREACH ( const Node* n, mList->list() ) lst.append( n->referencedColumns() ); return lst; }
1079  virtual bool needsGeometry() const override { bool needs = false; Q_FOREACH ( Node* n, mList->list() ) needs |= n->needsGeometry(); return needs; }
1080  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1081  virtual Node* clone() const override;
1082 
1083  protected:
1086  bool mNotIn;
1087  };
1088 
1089  class CORE_EXPORT NodeFunction : public Node
1090  {
1091  public:
1092  NodeFunction( int fnIndex, NodeList* args ) : mFnIndex( fnIndex )
1093  {
1094  const ParameterList& functionParams = Functions()[mFnIndex]->parameters();
1095  if ( !args || !args->hasNamedNodes() || functionParams.isEmpty() )
1096  {
1097  // no named parameters, or function does not support them
1098  mArgs = args;
1099  }
1100  else
1101  {
1102  mArgs = new NodeList();
1103 
1104  int idx = 0;
1105  //first loop through unnamed arguments
1106  while ( args->names().at( idx ).isEmpty() )
1107  {
1108  mArgs->append( args->list().at( idx )->clone() );
1109  idx++;
1110  }
1111 
1112  //next copy named parameters in order expected by function
1113  for ( ; idx < functionParams.count(); ++idx )
1114  {
1115  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1116  if ( nodeIdx < 0 )
1117  {
1118  //parameter not found - insert default value for parameter
1119  mArgs->append( new NodeLiteral( functionParams.at( idx ).defaultValue() ) );
1120  }
1121  else
1122  {
1123  mArgs->append( args->list().at( nodeIdx )->clone() );
1124  }
1125  }
1126 
1127  delete args;
1128  }
1129  }
1130 
1131  virtual ~NodeFunction() { delete mArgs; }
1132 
1133  int fnIndex() const { return mFnIndex; }
1134  NodeList* args() const { return mArgs; }
1135 
1136  virtual NodeType nodeType() const override { return ntFunction; }
1137  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1138  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1139  virtual QString dump() const override;
1140 
1141  virtual QStringList referencedColumns() const override;
1142  virtual bool needsGeometry() const override { bool needs = Functions()[mFnIndex]->usesgeometry(); if ( mArgs ) { Q_FOREACH ( Node* n, mArgs->list() ) needs |= n->needsGeometry(); } return needs; }
1143  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1144  virtual Node* clone() const override;
1145 
1147  static bool validateParams( int fnIndex, NodeList* args, QString& error )
1148  {
1149  if ( !args || !args->hasNamedNodes() )
1150  return true;
1151 
1152  const ParameterList& functionParams = Functions()[fnIndex]->parameters();
1153  if ( functionParams.isEmpty() )
1154  {
1155  error = QString( "%1 does not supported named parameters" ).arg( Functions()[fnIndex]->name() );
1156  return false;
1157  }
1158  else
1159  {
1160  QSet< int > providedArgs;
1161  QSet< int > handledArgs;
1162  int idx = 0;
1163  //first loop through unnamed arguments
1164  while ( args->names().at( idx ).isEmpty() )
1165  {
1166  providedArgs << idx;
1167  handledArgs << idx;
1168  idx++;
1169  }
1170 
1171  //next check named parameters
1172  for ( ; idx < functionParams.count(); ++idx )
1173  {
1174  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1175  if ( nodeIdx < 0 )
1176  {
1177  if ( !functionParams.at( idx ).optional() )
1178  {
1179  error = QString( "No value specified for parameter '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
1180  return false;
1181  }
1182  }
1183  else
1184  {
1185  if ( providedArgs.contains( idx ) )
1186  {
1187  error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
1188  return false;
1189  }
1190  }
1191  providedArgs << idx;
1192  handledArgs << nodeIdx;
1193  }
1194 
1195  //last check for bad names
1196  idx = 0;
1197  Q_FOREACH ( const QString& name, args->names() )
1198  {
1199  if ( !name.isEmpty() && !functionParams.contains( name ) )
1200  {
1201  error = QString( "Invalid parameter name '%1' for %2" ).arg( name, Functions()[fnIndex]->name() );
1202  return false;
1203  }
1204  if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1205  {
1206  int functionIdx = functionParams.indexOf( name );
1207  if ( providedArgs.contains( functionIdx ) )
1208  {
1209  error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(), Functions()[fnIndex]->name() );
1210  return false;
1211  }
1212  }
1213  idx++;
1214  }
1215 
1216  }
1217  return true;
1218  }
1219 
1220  protected:
1223 
1224  };
1225 
1226  class CORE_EXPORT NodeLiteral : public Node
1227  {
1228  public:
1229  NodeLiteral( const QVariant& value ) : mValue( value ) {}
1230 
1232  inline QVariant value() const { return mValue; }
1233 
1234  virtual NodeType nodeType() const override { return ntLiteral; }
1235  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1236  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1237  virtual QString dump() const override;
1238 
1239  virtual QStringList referencedColumns() const override { return QStringList(); }
1240  virtual bool needsGeometry() const override { return false; }
1241  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1242  virtual Node* clone() const override;
1243 
1244  protected:
1246  };
1247 
1248  class CORE_EXPORT NodeColumnRef : public Node
1249  {
1250  public:
1251  NodeColumnRef( const QString& name ) : mName( name ), mIndex( -1 ) {}
1252 
1254  QString name() const { return mName; }
1255 
1256  virtual NodeType nodeType() const override { return ntColumnRef; }
1257  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1258  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1259  virtual QString dump() const override;
1260 
1261  virtual QStringList referencedColumns() const override { return QStringList( mName ); }
1262  virtual bool needsGeometry() const override { return false; }
1263 
1264  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1265  virtual Node* clone() const override;
1266 
1267  protected:
1269  int mIndex;
1270  };
1271 
1272  class CORE_EXPORT WhenThen
1273  {
1274  public:
1275  WhenThen( Node* whenExp, Node* thenExp ) : mWhenExp( whenExp ), mThenExp( thenExp ) {}
1276  ~WhenThen() { delete mWhenExp; delete mThenExp; }
1277 
1278  // protected:
1281 
1282  private:
1283  WhenThen( const WhenThen& rh );
1284  WhenThen& operator=( const WhenThen& rh );
1285  };
1287 
1288  class CORE_EXPORT NodeCondition : public Node
1289  {
1290  public:
1291  NodeCondition( WhenThenList* conditions, Node* elseExp = nullptr ) : mConditions( *conditions ), mElseExp( elseExp ) { delete conditions; }
1292  NodeCondition( const WhenThenList& conditions, Node* elseExp = nullptr ) : mConditions( conditions ), mElseExp( elseExp ) {}
1293  ~NodeCondition() { delete mElseExp; qDeleteAll( mConditions ); }
1294 
1295  virtual NodeType nodeType() const override { return ntCondition; }
1296  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1297  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1298  virtual QString dump() const override;
1299 
1300  virtual QStringList referencedColumns() const override;
1301  virtual bool needsGeometry() const override;
1302  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1303  virtual Node* clone() const override;
1304 
1305  protected:
1306  WhenThenList mConditions;
1308  };
1309 
1311 
1314  class CORE_EXPORT Visitor
1315  {
1316  public:
1317  virtual ~Visitor() {}
1318  virtual void visit( const NodeUnaryOperator& n ) = 0;
1319  virtual void visit( const NodeBinaryOperator& n ) = 0;
1320  virtual void visit( const NodeInOperator& n ) = 0;
1321  virtual void visit( const NodeFunction& n ) = 0;
1322  virtual void visit( const NodeLiteral& n ) = 0;
1323  virtual void visit( const NodeColumnRef& n ) = 0;
1324  virtual void visit( const NodeCondition& n ) = 0;
1325  };
1326 
1328  void acceptVisitor( Visitor& v ) const;
1329 
1334  static QString helptext( QString name );
1335 
1343  static QString variableHelpText( const QString& variableName, bool showValue = true, const QVariant& value = QVariant() );
1344 
1348  static QString group( const QString& group );
1349 
1356  static QString formatPreviewString( const QVariant& value );
1357 
1358  protected:
1362  QgsExpression();
1363 
1364  void initGeomCalculator();
1365 
1368 
1369  struct HelpArg
1370  {
1371  HelpArg( const QString& arg, const QString& desc, bool descOnly = false, bool syntaxOnly = false,
1372  bool optional = false, const QString& defaultVal = QString() )
1373  : mArg( arg )
1374  , mDescription( desc )
1375  , mDescOnly( descOnly )
1376  , mSyntaxOnly( syntaxOnly )
1377  , mOptional( optional )
1378  , mDefaultVal( defaultVal )
1379  {}
1380 
1387  };
1388 
1390  {
1391  HelpExample( const QString& expression, const QString& returns, const QString& note = QString::null )
1392  : mExpression( expression )
1393  , mReturns( returns )
1394  , mNote( note )
1395  {}
1396 
1400  };
1401 
1403  {
1404  HelpVariant( const QString& name, const QString& description,
1405  const QList<HelpArg>& arguments = QList<HelpArg>(),
1406  bool variableLenArguments = false,
1407  const QList<HelpExample>& examples = QList<HelpExample>(),
1408  const QString& notes = QString::null )
1409  : mName( name )
1410  , mDescription( description )
1411  , mArguments( arguments )
1412  , mVariableLenArguments( variableLenArguments )
1413  , mExamples( examples )
1414  , mNotes( notes )
1415  {}
1416 
1423  };
1424 
1425  struct Help
1426  {
1427  Help() {}
1428 
1429  Help( const QString& name, const QString& type, const QString& description, const QList<HelpVariant>& variants )
1430  : mName( name )
1431  , mType( type )
1432  , mDescription( description )
1433  , mVariants( variants )
1434  {}
1435 
1440  };
1441 
1448  void detach();
1449 
1450  QgsExpressionPrivate* d;
1451 
1455 
1457  static void initFunctionHelp();
1459  static void initVariableHelp();
1460 
1461  friend class QgsOgcUtils;
1462 };
1463 
1464 
1466 
1467 Q_DECLARE_METATYPE( QgsExpression::Interval )
1468 Q_DECLARE_METATYPE( QgsExpression::Node* )
1469 
1470 #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