QGIS API Documentation  2.17.0-Master (0497e4a)
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 );
127 
133  QgsExpression& operator=( const QgsExpression& other );
134 
140  QgsExpression();
141 
142  ~QgsExpression();
143 
150  bool operator==( const QgsExpression& other ) const;
151 
158  bool isValid() const;
159 
161  bool hasParserError() const;
163  QString parserErrorString() const;
164 
165  class Node;
166 
168  const Node* rootNode() const;
169 
172  Q_DECL_DEPRECATED bool prepare( const QgsFields &fields );
173 
178  bool prepare( const QgsExpressionContext *context );
179 
189  QStringList referencedColumns() const;
190 
192  bool needsGeometry() const;
193 
194  // evaluation
195 
199  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature* f );
200 
205  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature& f );
206 
210  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature* f, const QgsFields& fields );
211 
216  Q_DECL_DEPRECATED QVariant evaluate( const QgsFeature& f, const QgsFields& fields );
217 
222  QVariant evaluate();
223 
229  QVariant evaluate( const QgsExpressionContext* context );
230 
232  bool hasEvalError() const;
234  QString evalErrorString() const;
236  void setEvalErrorString( const QString& str );
237 
240  Q_DECL_DEPRECATED void setCurrentRowNumber( int rowNumber );
243  Q_DECL_DEPRECATED int currentRowNumber(); //TODO QGIS 3.0: make the following methods private. They are still required for replaceExpressionText
244  //but should not be publicly used
248  Q_DECL_DEPRECATED static void setSpecialColumn( const QString& name, const QVariant& value );
252  Q_DECL_DEPRECATED static void unsetSpecialColumn( const QString& name );
256  Q_DECL_DEPRECATED static QVariant specialColumn( const QString& name );
257 
261  static bool hasSpecialColumn( const QString& name );
262 
266  bool isField() const { return rootNode() && dynamic_cast<const NodeColumnRef*>( rootNode() ) ;}
267 
269  Q_DECL_DEPRECATED static bool isValid( const QString& text, const QgsFields& fields, QString &errorMessage );
270 
278  static bool isValid( const QString& text, const QgsExpressionContext* context, QString &errorMessage );
279 
285  void setExpression( const QString& expression );
286 
287  void setScale( double scale );
288 
289  double scale();
290 
294  QString expression() const;
295 
300  QString dump() const;
301 
308  QgsDistanceArea *geomCalculator();
309 
316  //TODO QGIS 3.0 change calc to a pointer, so that calculator can be cleared by passing nullptr
317  void setGeomCalculator( const QgsDistanceArea &calc );
318 
325  QGis::UnitType distanceUnits() const;
326 
333  void setDistanceUnits( QGis::UnitType unit );
334 
341  QgsUnitTypes::AreaUnit areaUnits() const;
342 
349  void setAreaUnits( QgsUnitTypes::AreaUnit unit );
350 
364  Q_DECL_DEPRECATED static QString replaceExpressionText( const QString &action, const QgsFeature *feat,
365  QgsVectorLayer *layer,
366  const QMap<QString, QVariant> *substitutionMap = nullptr,
367  const QgsDistanceArea* distanceArea = nullptr );
368 
380  static QString replaceExpressionText( const QString &action, const QgsExpressionContext* context,
381  const QMap<QString, QVariant> *substitutionMap = nullptr,
382  const QgsDistanceArea* distanceArea = nullptr );
383 
393  static double evaluateToDouble( const QString& text, const double fallbackValue );
394 
400  {
403  };
404 
410  {
411  // logical
414 
415  // comparison
416  boEQ, // =
417  boNE, // <>
418  boLE, // <=
419  boGE, // >=
420  boLT, // <
421  boGT, // >
429 
430  // math
438 
439  // strings
441  };
442 
444  {
454  };
455 
457  static const char* BinaryOperatorText[];
458 
460  static const char* UnaryOperatorText[];
461 
466  class CORE_EXPORT Parameter
467  {
468  public:
469 
475  Parameter( const QString& name,
476  bool optional = false,
477  const QVariant& defaultValue = QVariant() )
478  : mName( name )
479  , mOptional( optional )
480  , mDefaultValue( defaultValue )
481  {}
482 
484  QString name() const { return mName; }
485 
487  bool optional() const { return mOptional; }
488 
490  QVariant defaultValue() const { return mDefaultValue; }
491 
492  bool operator==( const Parameter& other ) const
493  {
494  return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
495  }
496 
497  private:
498  QString mName;
499  bool mOptional;
500  QVariant mDefaultValue;
501  };
502 
505 
507  typedef QVariant( *FcnEval )( const QVariantList& values, const QgsFeature* f, QgsExpression* parent );
508 
511  typedef QVariant( *FcnEvalContext )( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent );
512 
516  class CORE_EXPORT Function
517  {
518  public:
519 
521  Function( const QString& fnname,
522  int params,
523  const QString& group,
524  const QString& helpText = QString(),
525  bool usesGeometry = false,
526  const QStringList& referencedColumns = QStringList(),
527  bool lazyEval = false,
528  bool handlesNull = false,
529  bool isContextual = false )
530  : mName( fnname )
531  , mParams( params )
532  , mUsesGeometry( usesGeometry )
533  , mGroup( group )
534  , mHelpText( helpText )
535  , mReferencedColumns( referencedColumns )
536  , mLazyEval( lazyEval )
537  , mHandlesNull( handlesNull )
538  , mIsContextual( isContextual )
539  {
540  }
541 
545  Function( const QString& fnname,
546  const ParameterList& params,
547  const QString& group,
548  const QString& helpText = QString(),
549  bool usesGeometry = false,
550  const QStringList& referencedColumns = QStringList(),
551  bool lazyEval = false,
552  bool handlesNull = false,
553  bool isContextual = false )
554  : mName( fnname )
555  , mParams( 0 )
556  , mParameterList( params )
557  , mUsesGeometry( usesGeometry )
558  , mGroup( group )
559  , mHelpText( helpText )
560  , mReferencedColumns( referencedColumns )
561  , mLazyEval( lazyEval )
562  , mHandlesNull( handlesNull )
563  , mIsContextual( isContextual )
564  {}
565 
566  virtual ~Function() {}
567 
569  QString name() const { return mName; }
570 
572  int params() const { return mParameterList.isEmpty() ? mParams : mParameterList.count(); }
573 
575  int minParams() const
576  {
577  if ( mParameterList.isEmpty() )
578  return mParams;
579 
580  int min = 0;
581  Q_FOREACH ( const Parameter& param, mParameterList )
582  {
583  if ( !param.optional() )
584  min++;
585  }
586  return min;
587  }
588 
592  const ParameterList& parameters() const { return mParameterList; }
593 
595  //TODO QGIS 3.0 - rename to usesGeometry()
596  bool usesgeometry() const { return mUsesGeometry; }
597 
603  virtual QStringList aliases() const { return QStringList(); }
604 
608  bool lazyEval() const { return mLazyEval; }
609 
610  virtual QStringList referencedColumns() const { return mReferencedColumns; }
611 
615  bool isContextual() const { return mIsContextual; }
616 
618  QString group() const { return mGroup; }
620  //TODO QGIS 3.0 - rename to helpText()
621  const QString helptext() const { return mHelpText.isEmpty() ? QgsExpression::helptext( mName ) : mHelpText; }
622 
624  Q_DECL_DEPRECATED virtual QVariant func( const QVariantList&, const QgsFeature*, QgsExpression* );
625 
633  //TODO QGIS 3.0 - rename python method
634  virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent );
635 
636  bool operator==( const Function& other ) const
637  {
638  if ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 )
639  return true;
640 
641  return false;
642  }
643 
644  virtual bool handlesNull() const { return mHandlesNull; }
645 
646  private:
647  QString mName;
648  int mParams;
649  ParameterList mParameterList;
650  bool mUsesGeometry;
651  QString mGroup;
652  QString mHelpText;
653  QStringList mReferencedColumns;
654  bool mLazyEval;
655  bool mHandlesNull;
656  bool mIsContextual; //if true function is only available through an expression context
657  };
658 
663  class StaticFunction : public Function
664  {
665  public:
667  Q_DECL_DEPRECATED StaticFunction( const QString& fnname,
668  int params,
669  FcnEval fcn,
670  const QString& group,
671  const QString& helpText = QString(),
672  bool usesGeometry = false,
673  const QStringList& referencedColumns = QStringList(),
674  bool lazyEval = false,
675  const QStringList& aliases = QStringList(),
676  bool handlesNull = false )
677  : Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval, handlesNull )
678  , mFnc( fcn )
679  , mContextFnc( nullptr )
680  , mAliases( aliases )
681  {}
682 
683  virtual ~StaticFunction() {}
684 
687  StaticFunction( const QString& fnname,
688  int params,
689  FcnEvalContext fcn,
690  const QString& group,
691  const QString& helpText = QString(),
692  bool usesGeometry = false,
693  const QStringList& referencedColumns = QStringList(),
694  bool lazyEval = false,
695  const QStringList& aliases = QStringList(),
696  bool handlesNull = false )
697  : Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval, handlesNull )
698  , mFnc( nullptr )
699  , mContextFnc( fcn )
700  , mAliases( aliases )
701  {}
702 
705  StaticFunction( const QString& fnname,
706  const ParameterList& params,
707  FcnEvalContext fcn,
708  const QString& group,
709  const QString& helpText = QString(),
710  bool usesGeometry = false,
711  const QStringList& referencedColumns = QStringList(),
712  bool lazyEval = false,
713  const QStringList& aliases = QStringList(),
714  bool handlesNull = false )
715  : Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval, handlesNull )
716  , mFnc( nullptr )
717  , mContextFnc( fcn )
718  , mAliases( aliases )
719  {}
720 
722  Q_DECL_DEPRECATED virtual QVariant func( const QVariantList& values, const QgsFeature* f, QgsExpression* parent ) override;
723 
730  virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent ) override
731  {
732  return mContextFnc ? mContextFnc( values, context, parent ) : QVariant();
733  }
734 
735  virtual QStringList aliases() const override { return mAliases; }
736 
737  private:
738  FcnEval mFnc;
739  FcnEvalContext mContextFnc;
740  QStringList mAliases;
741  };
742 
745  static const QList<Function*>& Functions();
746 
749  static const QStringList& BuiltinFunctions();
750 
757  static bool registerFunction( Function* function, bool transferOwnership = false );
758 
763  static bool unregisterFunction( const QString& name );
764 
768 
772  static void cleanRegisteredFunctions();
773 
775  static bool isFunctionName( const QString& name );
776 
778  static int functionIndex( const QString& name );
779 
783  static int functionCount();
784 
788  static QList<Function*> specialColumns();
789 
794  static QString quotedColumnRef( QString name );
795 
800  static QString quotedString( QString text );
801 
809  static QString quotedValue( const QVariant& value );
810 
819  static QString quotedValue( const QVariant& value, QVariant::Type type );
820 
822 
823  class Visitor; // visitor interface is defined below
824 
825  enum NodeType
826  {
833  ntCondition
834  };
835 
838  class CORE_EXPORT Node
839  {
840  public:
841  virtual ~Node() {}
842 
848  virtual NodeType nodeType() const = 0;
849 
855  Q_DECL_DEPRECATED virtual QVariant eval( QgsExpression* parent, const QgsFeature* f );
856 
862  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context );
863 
869  Q_DECL_DEPRECATED virtual bool prepare( QgsExpression* parent, const QgsFields &fields );
870 
876  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context );
877 
883  virtual QString dump() const = 0;
884 
893  virtual Node* clone() const = 0;
894 
905  virtual QStringList referencedColumns() const = 0;
906 
915  virtual bool needsGeometry() const = 0;
916 
932  virtual void accept( Visitor& v ) const = 0;
933  };
934 
938  class CORE_EXPORT NamedNode
939  {
940  public:
941 
946  NamedNode( const QString& name, Node* node )
947  : name( name )
948  , node( node )
949  {}
950 
953 
956  };
957 
960  class CORE_EXPORT NodeList
961  {
962  public:
963  NodeList() : mHasNamedNodes( false ) {}
964  virtual ~NodeList() { qDeleteAll( mList ); }
966  void append( Node* node ) { mList.append( node ); mNameList.append( QString() ); }
967 
971  void append( NamedNode* node ) { mList.append( node->node ); mNameList.append( node->name.toLower() ); mHasNamedNodes = true; }
972 
975  int count() const { return mList.count(); }
976 
979  bool hasNamedNodes() const { return mHasNamedNodes; }
980 
981  QList<Node*> list() { return mList; }
982 
985  QStringList names() const { return mNameList; }
986 
988  NodeList* clone() const;
989 
990  virtual QString dump() const;
991 
992  protected:
995 
996  private:
997 
998  bool mHasNamedNodes;
999  };
1000 
1001  //TODO QGIS 3.0 - remove
1005 
1008  class CORE_EXPORT NodeUnaryOperator : public Node
1009  {
1010  public:
1012  : mOp( op )
1013  , mOperand( operand )
1014  {}
1015  ~NodeUnaryOperator() { delete mOperand; }
1016 
1017  UnaryOperator op() const { return mOp; }
1018  Node* operand() const { return mOperand; }
1019 
1020  virtual NodeType nodeType() const override { return ntUnaryOperator; }
1021  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1022  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1023  virtual QString dump() const override;
1024 
1025  virtual QStringList referencedColumns() const override { return mOperand->referencedColumns(); }
1026  virtual bool needsGeometry() const override { return mOperand->needsGeometry(); }
1027  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1028  virtual Node* clone() const override;
1029 
1030  protected:
1033  };
1034 
1037  class CORE_EXPORT NodeBinaryOperator : public Node
1038  {
1039  public:
1040  NodeBinaryOperator( BinaryOperator op, Node* opLeft, Node* opRight )
1041  : mOp( op )
1042  , mOpLeft( opLeft )
1043  , mOpRight( opRight )
1044  {}
1045  ~NodeBinaryOperator() { delete mOpLeft; delete mOpRight; }
1046 
1047  BinaryOperator op() const { return mOp; }
1048  Node* opLeft() const { return mOpLeft; }
1049  Node* opRight() const { return mOpRight; }
1050 
1051  virtual NodeType nodeType() const override { return ntBinaryOperator; }
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 { return mOpLeft->referencedColumns() + mOpRight->referencedColumns(); }
1057  virtual bool needsGeometry() const override { return mOpLeft->needsGeometry() || mOpRight->needsGeometry(); }
1058  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1059  virtual Node* clone() const override;
1060 
1061  int precedence() const;
1062  bool leftAssociative() const;
1063 
1064  protected:
1065  bool compare( double diff );
1066  int computeInt( int x, int y );
1067  double computeDouble( double x, double y );
1068 
1073  QDateTime computeDateTimeFromInterval( const QDateTime& d, QgsInterval* i );
1074 
1078  };
1079 
1082  class CORE_EXPORT NodeInOperator : public Node
1083  {
1084  public:
1085  NodeInOperator( Node* node, NodeList* list, bool notin = false )
1086  : mNode( node )
1087  , mList( list )
1088  , mNotIn( notin )
1089  {}
1090  virtual ~NodeInOperator() { delete mNode; delete mList; }
1091 
1092  Node* node() const { return mNode; }
1093  bool isNotIn() const { return mNotIn; }
1094  NodeList* list() const { return mList; }
1095 
1096  virtual NodeType nodeType() const override { return ntInOperator; }
1097  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1098  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1099  virtual QString dump() const override;
1100 
1101  virtual QStringList referencedColumns() const override { QStringList lst( mNode->referencedColumns() ); Q_FOREACH ( const Node* n, mList->list() ) lst.append( n->referencedColumns() ); return lst; }
1102  virtual bool needsGeometry() const override { bool needs = false; Q_FOREACH ( Node* n, mList->list() ) needs |= n->needsGeometry(); return needs; }
1103  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1104  virtual Node* clone() const override;
1105 
1106  protected:
1109  bool mNotIn;
1110  };
1111 
1114  class CORE_EXPORT NodeFunction : public Node
1115  {
1116  public:
1117  NodeFunction( int fnIndex, NodeList* args ) : mFnIndex( fnIndex )
1118  {
1119  const ParameterList& functionParams = Functions()[mFnIndex]->parameters();
1120  if ( !args || !args->hasNamedNodes() || functionParams.isEmpty() )
1121  {
1122  // no named parameters, or function does not support them
1123  mArgs = args;
1124  }
1125  else
1126  {
1127  mArgs = new NodeList();
1128 
1129  int idx = 0;
1130  //first loop through unnamed arguments
1131  while ( args->names().at( idx ).isEmpty() )
1132  {
1133  mArgs->append( args->list().at( idx )->clone() );
1134  idx++;
1135  }
1136 
1137  //next copy named parameters in order expected by function
1138  for ( ; idx < functionParams.count(); ++idx )
1139  {
1140  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1141  if ( nodeIdx < 0 )
1142  {
1143  //parameter not found - insert default value for parameter
1144  mArgs->append( new NodeLiteral( functionParams.at( idx ).defaultValue() ) );
1145  }
1146  else
1147  {
1148  mArgs->append( args->list().at( nodeIdx )->clone() );
1149  }
1150  }
1151 
1152  delete args;
1153  }
1154  }
1155 
1156  virtual ~NodeFunction() { delete mArgs; }
1157 
1158  int fnIndex() const { return mFnIndex; }
1159  NodeList* args() const { return mArgs; }
1160 
1161  virtual NodeType nodeType() const override { return ntFunction; }
1162  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1163  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1164  virtual QString dump() const override;
1165 
1166  virtual QStringList referencedColumns() const override;
1167  virtual bool needsGeometry() const override { bool needs = Functions()[mFnIndex]->usesgeometry(); if ( mArgs ) { Q_FOREACH ( Node* n, mArgs->list() ) needs |= n->needsGeometry(); } return needs; }
1168  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1169  virtual Node* clone() const override;
1170 
1172  static bool validateParams( int fnIndex, NodeList* args, QString& error )
1173  {
1174  if ( !args || !args->hasNamedNodes() )
1175  return true;
1176 
1177  const ParameterList& functionParams = Functions()[fnIndex]->parameters();
1178  if ( functionParams.isEmpty() )
1179  {
1180  error = QString( "%1 does not supported named parameters" ).arg( Functions()[fnIndex]->name() );
1181  return false;
1182  }
1183  else
1184  {
1185  QSet< int > providedArgs;
1186  QSet< int > handledArgs;
1187  int idx = 0;
1188  //first loop through unnamed arguments
1189  while ( args->names().at( idx ).isEmpty() )
1190  {
1191  providedArgs << idx;
1192  handledArgs << idx;
1193  idx++;
1194  }
1195 
1196  //next check named parameters
1197  for ( ; idx < functionParams.count(); ++idx )
1198  {
1199  int nodeIdx = args->names().indexOf( functionParams.at( idx ).name().toLower() );
1200  if ( nodeIdx < 0 )
1201  {
1202  if ( !functionParams.at( idx ).optional() )
1203  {
1204  error = QString( "No value specified for parameter '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
1205  return false;
1206  }
1207  }
1208  else
1209  {
1210  if ( providedArgs.contains( idx ) )
1211  {
1212  error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(), Functions()[fnIndex]->name() );
1213  return false;
1214  }
1215  }
1216  providedArgs << idx;
1217  handledArgs << nodeIdx;
1218  }
1219 
1220  //last check for bad names
1221  idx = 0;
1222  Q_FOREACH ( const QString& name, args->names() )
1223  {
1224  if ( !name.isEmpty() && !functionParams.contains( name ) )
1225  {
1226  error = QString( "Invalid parameter name '%1' for %2" ).arg( name, Functions()[fnIndex]->name() );
1227  return false;
1228  }
1229  if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1230  {
1231  int functionIdx = functionParams.indexOf( name );
1232  if ( providedArgs.contains( functionIdx ) )
1233  {
1234  error = QString( "Duplicate parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(), Functions()[fnIndex]->name() );
1235  return false;
1236  }
1237  }
1238  idx++;
1239  }
1240 
1241  }
1242  return true;
1243  }
1244 
1245  protected:
1248 
1249  };
1250 
1253  class CORE_EXPORT NodeLiteral : public Node
1254  {
1255  public:
1256  NodeLiteral( const QVariant& value )
1257  : mValue( value )
1258  {}
1259 
1261  inline QVariant value() const { return mValue; }
1262 
1263  virtual NodeType nodeType() const override { return ntLiteral; }
1264  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1265  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1266  virtual QString dump() const override;
1267 
1268  virtual QStringList referencedColumns() const override { return QStringList(); }
1269  virtual bool needsGeometry() const override { return false; }
1270  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1271  virtual Node* clone() const override;
1272 
1273  protected:
1275  };
1276 
1279  class CORE_EXPORT NodeColumnRef : public Node
1280  {
1281  public:
1282  NodeColumnRef( const QString& name )
1283  : mName( name )
1284  , mIndex( -1 )
1285  {}
1286 
1288  QString name() const { return mName; }
1289 
1290  virtual NodeType nodeType() const override { return ntColumnRef; }
1291  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1292  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1293  virtual QString dump() const override;
1294 
1295  virtual QStringList referencedColumns() const override { return QStringList( mName ); }
1296  virtual bool needsGeometry() const override { return false; }
1297 
1298  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1299  virtual Node* clone() const override;
1300 
1301  protected:
1303  int mIndex;
1304  };
1305 
1308  class CORE_EXPORT WhenThen
1309  {
1310  public:
1311  WhenThen( Node* whenExp, Node* thenExp )
1312  : mWhenExp( whenExp )
1313  , mThenExp( thenExp )
1314  {}
1315  ~WhenThen() { delete mWhenExp; delete mThenExp; }
1316 
1317  // protected:
1320 
1321  private:
1322  WhenThen( const WhenThen& rh );
1323  WhenThen& operator=( const WhenThen& rh );
1324  };
1326 
1329  class CORE_EXPORT NodeCondition : public Node
1330  {
1331  public:
1332  NodeCondition( WhenThenList* conditions, Node* elseExp = nullptr )
1333  : mConditions( *conditions )
1334  , mElseExp( elseExp )
1335  { delete conditions; }
1336  NodeCondition( const WhenThenList& conditions, Node* elseExp = nullptr )
1337  : mConditions( conditions )
1338  , mElseExp( elseExp )
1339  {}
1340  ~NodeCondition() { delete mElseExp; qDeleteAll( mConditions ); }
1341 
1342  virtual NodeType nodeType() const override { return ntCondition; }
1343  virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) override;
1344  virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) override;
1345  virtual QString dump() const override;
1346 
1347  virtual QStringList referencedColumns() const override;
1348  virtual bool needsGeometry() const override;
1349  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
1350  virtual Node* clone() const override;
1351 
1352  protected:
1353  WhenThenList mConditions;
1355  };
1356 
1358 
1362  class CORE_EXPORT Visitor
1363  {
1364  public:
1365  virtual ~Visitor() {}
1366  virtual void visit( const NodeUnaryOperator& n ) = 0;
1367  virtual void visit( const NodeBinaryOperator& n ) = 0;
1368  virtual void visit( const NodeInOperator& n ) = 0;
1369  virtual void visit( const NodeFunction& n ) = 0;
1370  virtual void visit( const NodeLiteral& n ) = 0;
1371  virtual void visit( const NodeColumnRef& n ) = 0;
1372  virtual void visit( const NodeCondition& n ) = 0;
1373  };
1374 
1376  void acceptVisitor( Visitor& v ) const;
1377 
1382  static QString helptext( QString name );
1383 
1391  static QString variableHelpText( const QString& variableName, bool showValue = true, const QVariant& value = QVariant() );
1392 
1396  static QString group( const QString& group );
1397 
1404  static QString formatPreviewString( const QVariant& value );
1405 
1406  protected:
1407  void initGeomCalculator();
1408 
1411 
1412  struct HelpArg
1413  {
1414  HelpArg( const QString& arg, const QString& desc, bool descOnly = false, bool syntaxOnly = false,
1415  bool optional = false, const QString& defaultVal = QString() )
1416  : mArg( arg )
1417  , mDescription( desc )
1418  , mDescOnly( descOnly )
1419  , mSyntaxOnly( syntaxOnly )
1420  , mOptional( optional )
1421  , mDefaultVal( defaultVal )
1422  {}
1423 
1430  };
1431 
1433  {
1434  HelpExample( const QString& expression, const QString& returns, const QString& note = QString::null )
1435  : mExpression( expression )
1436  , mReturns( returns )
1437  , mNote( note )
1438  {}
1439 
1443  };
1444 
1446  {
1447  HelpVariant( const QString& name, const QString& description,
1448  const QList<HelpArg>& arguments = QList<HelpArg>(),
1449  bool variableLenArguments = false,
1450  const QList<HelpExample>& examples = QList<HelpExample>(),
1451  const QString& notes = QString::null )
1452  : mName( name )
1453  , mDescription( description )
1454  , mArguments( arguments )
1455  , mVariableLenArguments( variableLenArguments )
1456  , mExamples( examples )
1457  , mNotes( notes )
1458  {}
1459 
1466  };
1467 
1468  struct Help
1469  {
1470  Help() {}
1471 
1472  Help( const QString& name, const QString& type, const QString& description, const QList<HelpVariant>& variants )
1473  : mName( name )
1474  , mType( type )
1475  , mDescription( description )
1476  , mVariants( variants )
1477  {}
1478 
1483  };
1484 
1491  void detach();
1492 
1493  QgsExpressionPrivate* d;
1494 
1498 
1500  static void initFunctionHelp();
1502  static void initVariableHelp();
1503 
1504  friend class QgsOgcUtils;
1505 };
1506 
1507 
1509 
1511 
1512 #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...
const QString helptext() const
The help text for the function.
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.
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.
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)
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:252
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
int count() const
Returns the number of nodes in the list.
virtual QStringList referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node...
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.
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 lazyEval() const
True if this function should use lazy evaluation.
QString name() const
Returns the name of the parameter.
QString group() const
The group the function belongs to.
virtual bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
virtual bool handlesNull() const
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
virtual QStringList referencedColumns() const
bool operator==(const Parameter &other) const
NodeCondition(WhenThenList *conditions, Node *elseExp=nullptr)
QVariant defaultValue() const
Returns the default value for the parameter.
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
QList< Parameter > ParameterList
List of parameters, used for function definition.
virtual void accept(Visitor &v) const override
Support the visitor pattern.
bool hasNamedNodes() const
Returns true if list contains any named nodes.
QStringList names() const
Returns a list of names for nodes.
QList< Node * > mList
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.
bool operator==(const Function &other) const
Represents a single parameter passed to a function.
NodeInOperator(Node *node, NodeList *list, bool notin=false)
QString name() const
The name of the function.
Help(const QString &name, const QString &type, const QString &description, const QList< HelpVariant > &variants)
static QHash< QString, QString > gVariableHelpTexts
bool isContextual() const
Returns whether the function is only available if provided by a QgsExpressionContext object...
QList< HelpArg > mArguments
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)
bool usesgeometry() const
Does this function use a geometry object.
QString toLower() 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 optional() const
Returns true if the parameter is optional.
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 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
QString name() const
The name of the column.
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.
static QHash< QString, Help > gFunctionHelpTexts
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 void visit(const NodeUnaryOperator &n)=0
virtual QStringList aliases() const
Returns a list of possible aliases for the function.
QVariant value() const
The value of the literal.
NodeLiteral(const QVariant &value)
bool isField() const
Checks whether an expression consists only of a single field reference.
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...
NamedNode(const QString &name, Node *node)
Constructor for NamedNode.
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
int params() const
The number of parameters this function takes.
void append(Node *node)
Takes ownership of the provided node.
virtual void accept(Visitor &v) const override
Support the visitor pattern.
int minParams() const
The mininum number of parameters this function takes.
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.
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.
const ParameterList & parameters() const
Returns the list of named parameters for the function, if set.
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