QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
qgsexpressionfunction.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpressionfunction.h
3  -------------------
4  begin : May 2017
5  copyright : (C) 2017 Matthias Kuhn
6  email : [email protected]
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 QGSEXPRESSIONFUNCTION_H
17 #define QGSEXPRESSIONFUNCTION_H
18 
19 #include <functional>
20 
21 #include <QString>
22 #include <QVariant>
23 #include <QSet>
24 #include <QJsonDocument>
25 #include <QJsonObject>
26 
27 #include "qgis.h"
28 #include "qgis_core.h"
29 #include "qgsexpressionnode.h"
30 
32 class QgsExpression;
35 
40 class CORE_EXPORT QgsExpressionFunction
41 {
42  public:
43 
47  typedef QVariant( *FcnEval )( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) SIP_SKIP;
48 
53  class CORE_EXPORT Parameter
54  {
55  public:
56 
64  Parameter( const QString &name,
65  bool optional = false,
66  const QVariant &defaultValue = QVariant(),
67  bool isSubExpression = false )
68  : mName( name )
69  , mOptional( optional )
70  , mDefaultValue( defaultValue )
71  , mIsSubExpression( isSubExpression )
72  {}
73 
75  QString name() const { return mName; }
76 
78  bool optional() const { return mOptional; }
79 
81  QVariant defaultValue() const { return mDefaultValue; }
82 
88  bool isSubExpression() const { return mIsSubExpression; }
89 
90  bool operator==( const QgsExpressionFunction::Parameter &other ) const
91  {
92  return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
93  }
94 
95  private:
96  QString mName;
97  bool mOptional = false;
98  QVariant mDefaultValue;
99  bool mIsSubExpression = false;
100  };
101 
103  typedef QList< QgsExpressionFunction::Parameter > ParameterList;
104 
106  QgsExpressionFunction( const QString &fnname,
107  int params,
108  const QString &group,
109  const QString &helpText = QString(),
110  bool lazyEval = false,
111  bool handlesNull = false,
112  bool isContextual = false )
113  : mName( fnname )
114  , mParams( params )
115  , mGroups( group.isEmpty() ? QStringList() : QStringList() << group )
116  , mHelpText( helpText )
117  , mLazyEval( lazyEval )
118  , mHandlesNull( handlesNull )
119  , mIsContextual( isContextual )
120  {
121  }
122 
126  QgsExpressionFunction( const QString &fnname,
127  int params,
128  const QStringList &groups,
129  const QString &helpText = QString(),
130  bool lazyEval = false,
131  bool handlesNull = false,
132  bool isContextual = false )
133  : mName( fnname )
134  , mParams( params )
135  , mGroups( groups )
136  , mHelpText( helpText )
137  , mLazyEval( lazyEval )
138  , mHandlesNull( handlesNull )
139  , mIsContextual( isContextual )
140  {
141  }
142 
146  QgsExpressionFunction( const QString &fnname,
148  const QString &group,
149  const QString &helpText = QString(),
150  bool lazyEval = false,
151  bool handlesNull = false,
152  bool isContextual = false )
153  : mName( fnname )
154  , mParams( 0 )
155  , mParameterList( params )
156  , mGroups( group.isEmpty() ? QStringList() : QStringList() << group )
157  , mHelpText( helpText )
158  , mLazyEval( lazyEval )
159  , mHandlesNull( handlesNull )
160  , mIsContextual( isContextual )
161  {}
162 
166  QgsExpressionFunction( const QString &fnname,
168  const QStringList &groups,
169  const QString &helpText = QString(),
170  bool lazyEval = false,
171  bool handlesNull = false,
172  bool isContextual = false )
173  : mName( fnname )
174  , mParams( 0 )
175  , mParameterList( params )
176  , mGroups( groups )
177  , mHelpText( helpText )
178  , mLazyEval( lazyEval )
179  , mHandlesNull( handlesNull )
180  , mIsContextual( isContextual )
181  {}
182 
183  virtual ~QgsExpressionFunction() = default;
184 
186  QString name() const { return mName; }
187 
189  int params() const { return mParameterList.isEmpty() ? mParams : mParameterList.count(); }
190 
192  int minParams() const
193  {
194  if ( mParameterList.isEmpty() )
195  return mParams;
196 
197  int min = 0;
198  for ( const Parameter &param : mParameterList )
199  {
200  if ( !param.optional() )
201  min++;
202  }
203  return min;
204  }
205 
209  const QgsExpressionFunction::ParameterList &parameters() const { return mParameterList; }
210 
212  virtual bool usesGeometry( const QgsExpressionNodeFunction *node ) const;
213 
219  virtual QStringList aliases() const;
220 
226  bool lazyEval() const { return mLazyEval; }
227 
237  virtual bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
238 
246  virtual bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
247 
255  virtual QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const;
256 
260  bool isContextual() const { return mIsContextual; }
261 
266  virtual bool isDeprecated() const;
267 
272  QString group() const { return mGroups.isEmpty() ? QString() : mGroups.at( 0 ); }
273 
278  QStringList groups() const { return mGroups; }
279 
281  const QString helpText() const;
282 
291  virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) = 0;
292 
297  virtual QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node );
298 
299  bool operator==( const QgsExpressionFunction &other ) const;
300 
305  virtual bool handlesNull() const;
306 
307  protected:
308 
317  static bool allParamsStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context );
318 
319  private:
320  QString mName;
321  int mParams;
323  QStringList mGroups;
324  QString mHelpText;
325  bool mLazyEval;
326  bool mHandlesNull;
327  bool mIsContextual; //if true function is only available through an expression context
328 };
329 
335 #ifndef SIP_RUN
337 {
338  public:
339 
343  QgsStaticExpressionFunction( const QString &fnname,
344  int params,
345  FcnEval fcn,
346  const QString &group,
347  const QString &helpText = QString(),
348  bool usesGeometry = false,
349  const QSet<QString> &referencedColumns = QSet<QString>(),
350  bool lazyEval = false,
351  const QStringList &aliases = QStringList(),
352  bool handlesNull = false )
354  , mFnc( fcn )
355  , mAliases( aliases )
356  , mUsesGeometry( usesGeometry )
357  , mReferencedColumns( referencedColumns )
358  {
359  }
360 
365  QgsStaticExpressionFunction( const QString &fnname,
366  int params,
367  FcnEval fcn,
368  const QStringList &groups,
369  const QString &helpText = QString(),
370  bool usesGeometry = false,
371  const QSet<QString> &referencedColumns = QSet<QString>(),
372  bool lazyEval = false,
373  const QStringList &aliases = QStringList(),
374  bool handlesNull = false )
376  , mFnc( fcn )
377  , mAliases( aliases )
378  , mUsesGeometry( usesGeometry )
379  , mReferencedColumns( referencedColumns )
380  {
381  }
382 
386  QgsStaticExpressionFunction( const QString &fnname,
388  FcnEval fcn,
389  const QString &group,
390  const QString &helpText = QString(),
391  bool usesGeometry = false,
392  const QSet<QString> &referencedColumns = QSet<QString>(),
393  bool lazyEval = false,
394  const QStringList &aliases = QStringList(),
395  bool handlesNull = false )
397  , mFnc( fcn )
398  , mAliases( aliases )
399  , mUsesGeometry( usesGeometry )
400  , mReferencedColumns( referencedColumns )
401  {}
402 
414  QgsStaticExpressionFunction( const QString &fnname,
416  FcnEval fcn,
417  const QString &group,
418  const QString &helpText,
419  const std::function< bool( const QgsExpressionNodeFunction *node )> &usesGeometry,
420  const std::function< QSet<QString>( const QgsExpressionNodeFunction *node )> &referencedColumns,
421  bool lazyEval = false,
422  const QStringList &aliases = QStringList(),
423  bool handlesNull = false );
424 
429  QgsStaticExpressionFunction( const QString &fnname,
431  FcnEval fcn,
432  const QStringList &groups,
433  const QString &helpText = QString(),
434  bool usesGeometry = false,
435  const QSet<QString> &referencedColumns = QSet<QString>(),
436  bool lazyEval = false,
437  const QStringList &aliases = QStringList(),
438  bool handlesNull = false )
440  , mFnc( fcn )
441  , mAliases( aliases )
442  , mUsesGeometry( usesGeometry )
443  , mReferencedColumns( referencedColumns )
444  {}
445 
454  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override
455  {
456  return mFnc ? mFnc( values, context, parent, node ) : QVariant();
457  }
458 
459  QStringList aliases() const override;
460 
461  bool usesGeometry( const QgsExpressionNodeFunction *node ) const override;
462 
468  void setUsesGeometryFunction( const std::function< bool( const QgsExpressionNodeFunction *node )> &usesGeometry );
469 
470  QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const override;
471 
472  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
473 
474  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
475 
482  void setIsStaticFunction( const std::function< bool ( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) > &isStatic );
483 
484 
492  void setIsStatic( bool isStatic );
493 
500  void setPrepareFunction( const std::function< bool( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * )> &prepareFunc );
501 
505  static const QList<QgsExpressionFunction *> &functions();
506 
507  private:
508  FcnEval mFnc;
509  QStringList mAliases;
510  bool mUsesGeometry;
511  std::function < bool( const QgsExpressionNodeFunction *node ) > mUsesGeometryFunc;
512  std::function < QSet<QString>( const QgsExpressionNodeFunction *node ) > mReferencedColumnsFunc;
513  std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mIsStaticFunc = allParamsStatic;
514  std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mPrepareFunc;
515  QSet<QString> mReferencedColumns;
516  bool mIsStatic = false;
517 };
518 
528 {
529  public:
531 
532  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
533 
534  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
535 
536  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
537 
538  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
539 
540 };
541 
551 {
552  public:
554 
555  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
556 
557  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
558 
559  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
560 
561  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
562 
563 };
564 
574 {
575  public:
577 
578  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
579 
580  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
581 
582  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
583 
584  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
585 
586  private:
587 
591  void appendTemporaryVariable( const QgsExpressionContext *context, const QString &name, const QVariant &value ) const;
592 
596  void popTemporaryVariable( const QgsExpressionContext *context ) const;
597 };
598 
599 #endif
600 
601 #endif // QGSEXPRESSIONFUNCTION_H
Handles the array_filter(array, expression) expression function.
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
Handles the array loopingarray_Foreach(array, expression) expression function.
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
Single scope for storing variables and functions for use within a QgsExpressionContext.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Represents a single parameter passed to a function.
Parameter(const QString &name, bool optional=false, const QVariant &defaultValue=QVariant(), bool isSubExpression=false)
Constructor for Parameter.
bool operator==(const QgsExpressionFunction::Parameter &other) const
QVariant defaultValue() const
Returns the default value for the parameter.
QString name() const
Returns the name of the parameter.
bool isSubExpression() const
Returns true if parameter argument is a separate sub-expression, and should not be checked while dete...
bool optional() const
Returns true if the parameter is optional.
A abstract base class for defining QgsExpression functions.
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
QgsExpressionFunction(const QString &fnname, const QgsExpressionFunction::ParameterList &params, const QStringList &groups, const QString &helpText=QString(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses named parameter list and group list.
bool isContextual() const
Returns whether the function is only available if provided by a QgsExpressionContext object.
int params() const
The number of parameters this function takes.
QStringList groups() const
Returns a list of the groups the function belongs to.
QgsExpressionFunction(const QString &fnname, int params, const QString &group, const QString &helpText=QString(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses unnamed parameters.
bool lazyEval() const
true if this function should use lazy evaluation.
static bool allParamsStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context)
This will return true if all the params for the provided function node are static within the constrai...
virtual ~QgsExpressionFunction()=default
int minParams() const
The minimum number of parameters this function takes.
QgsExpressionFunction(const QString &fnname, int params, const QStringList &groups, const QString &helpText=QString(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses unnamed parameters and group list.
QString name() const
The name of the function.
QString group() const
Returns the first group which the function belongs to.
virtual QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)=0
Returns result of evaluating the function.
const QgsExpressionFunction::ParameterList & parameters() const
Returns the list of named parameters for the function, if set.
virtual bool handlesNull() const
Returns true if the function handles NULL values in arguments by itself, and the default NULL value h...
const QString helpText() const
The help text for the function.
QVariant(* FcnEval)(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
Function definition for evaluation against an expression context, using a list of values as parameter...
QgsExpressionFunction(const QString &fnname, const QgsExpressionFunction::ParameterList &params, const QString &group, const QString &helpText=QString(), bool lazyEval=false, bool handlesNull=false, bool isContextual=false)
Constructor for function which uses named parameter list.
An expression node for expression functions.
A list of expression nodes.
Class for parsing and evaluation of expressions (formerly called "search strings").
c++ helper class for defining QgsExpression functions.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
QgsStaticExpressionFunction(const QString &fnname, const QgsExpressionFunction::ParameterList &params, FcnEval fcn, const QStringList &groups, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using a named list of parameter values...
void setIsStaticFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *) > &isStatic)
Set a function that will be called in the prepare step to determine if the function is static or not.
QStringList aliases() const override
Returns a list of possible aliases for the function.
void setPrepareFunction(const std::function< bool(const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext *)> &prepareFunc)
Set a function that will be called in the prepare step to determine if the function is static or not.
void setUsesGeometryFunction(const std::function< bool(const QgsExpressionNodeFunction *node)> &usesGeometry)
Set a function that will be called when determining if the function requires feature geometry or not.
QgsStaticExpressionFunction(const QString &fnname, const QgsExpressionFunction::ParameterList &params, FcnEval fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using a named list of parameter values...
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
void setIsStatic(bool isStatic)
Tag this function as either static or not static.
static const QList< QgsExpressionFunction * > & functions()
Returns a list of all registered expression functions.
QgsStaticExpressionFunction(const QString &fnname, const QgsExpressionFunction::ParameterList &params, FcnEval fcn, const QString &group, const QString &helpText, const std::function< bool(const QgsExpressionNodeFunction *node)> &usesGeometry, const std::function< QSet< QString >(const QgsExpressionNodeFunction *node)> &referencedColumns, bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using a named list of parameter values...
QgsStaticExpressionFunction(const QString &fnname, int params, FcnEval fcn, const QStringList &groups, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using an unnamed list of parameter val...
QgsStaticExpressionFunction(const QString &fnname, int params, FcnEval fcn, const QString &group, const QString &helpText=QString(), bool usesGeometry=false, const QSet< QString > &referencedColumns=QSet< QString >(), bool lazyEval=false, const QStringList &aliases=QStringList(), bool handlesNull=false)
Static function for evaluation against a QgsExpressionContext, using an unnamed list of parameter val...
QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const override
Returns a set of field names which are required for this function.
bool usesGeometry(const QgsExpressionNodeFunction *node) const override
Does this function use a geometry object.
Handles the with_variable(name, value, node) expression function.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Evaluates the function, first evaluating all required arguments before passing them to the function's...
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override
Returns result of evaluating the function.
bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
This will be called during the prepare step() of an expression if it is not static.
#define SIP_SKIP
Definition: qgis_sip.h:126
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)