QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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 
54  class CORE_EXPORT Parameter
55  {
56  public:
57 
65  Parameter( const QString &name,
66  bool optional = false,
67  const QVariant &defaultValue = QVariant(),
68  bool isSubExpression = false )
69  : mName( name )
70  , mOptional( optional )
71  , mDefaultValue( defaultValue )
72  , mIsSubExpression( isSubExpression )
73  {}
74 
76  QString name() const { return mName; }
77 
79  bool optional() const { return mOptional; }
80 
82  QVariant defaultValue() const { return mDefaultValue; }
83 
89  bool isSubExpression() const { return mIsSubExpression; }
90 
91  bool operator==( const QgsExpressionFunction::Parameter &other ) const
92  {
93  return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
94  }
95 
96  private:
97  QString mName;
98  bool mOptional = false;
99  QVariant mDefaultValue;
100  bool mIsSubExpression = false;
101  };
102 
104  typedef QList< QgsExpressionFunction::Parameter > ParameterList;
105 
107  QgsExpressionFunction( const QString &fnname,
108  int params,
109  const QString &group,
110  const QString &helpText = QString(),
111  bool lazyEval = false,
112  bool handlesNull = false,
113  bool isContextual = false )
114  : mName( fnname )
115  , mParams( params )
116  , mGroups( group.isEmpty() ? QStringList() : QStringList() << group )
117  , mHelpText( helpText )
118  , mLazyEval( lazyEval )
119  , mHandlesNull( handlesNull )
120  , mIsContextual( isContextual )
121  {
122  }
123 
128  QgsExpressionFunction( const QString &fnname,
129  int params,
130  const QStringList &groups,
131  const QString &helpText = QString(),
132  bool lazyEval = false,
133  bool handlesNull = false,
134  bool isContextual = false )
135  : mName( fnname )
136  , mParams( params )
137  , mGroups( groups )
138  , mHelpText( helpText )
139  , mLazyEval( lazyEval )
140  , mHandlesNull( handlesNull )
141  , mIsContextual( isContextual )
142  {
143  }
144 
149  QgsExpressionFunction( const QString &fnname,
151  const QString &group,
152  const QString &helpText = QString(),
153  bool lazyEval = false,
154  bool handlesNull = false,
155  bool isContextual = false )
156  : mName( fnname )
157  , mParams( 0 )
158  , mParameterList( params )
159  , mGroups( group.isEmpty() ? QStringList() : QStringList() << group )
160  , mHelpText( helpText )
161  , mLazyEval( lazyEval )
162  , mHandlesNull( handlesNull )
163  , mIsContextual( isContextual )
164  {}
165 
170  QgsExpressionFunction( const QString &fnname,
172  const QStringList &groups,
173  const QString &helpText = QString(),
174  bool lazyEval = false,
175  bool handlesNull = false,
176  bool isContextual = false )
177  : mName( fnname )
178  , mParams( 0 )
179  , mParameterList( params )
180  , mGroups( groups )
181  , mHelpText( helpText )
182  , mLazyEval( lazyEval )
183  , mHandlesNull( handlesNull )
184  , mIsContextual( isContextual )
185  {}
186 
187  virtual ~QgsExpressionFunction() = default;
188 
190  QString name() const { return mName; }
191 
193  int params() const { return mParameterList.isEmpty() ? mParams : mParameterList.count(); }
194 
196  int minParams() const
197  {
198  if ( mParameterList.isEmpty() )
199  return mParams;
200 
201  int min = 0;
202  for ( const Parameter &param : mParameterList )
203  {
204  if ( !param.optional() )
205  min++;
206  }
207  return min;
208  }
209 
214  const QgsExpressionFunction::ParameterList &parameters() const { return mParameterList; }
215 
217  virtual bool usesGeometry( const QgsExpressionNodeFunction *node ) const;
218 
225  virtual QStringList aliases() const;
226 
232  bool lazyEval() const { return mLazyEval; }
233 
244  virtual bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
245 
254  virtual bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
255 
264  virtual QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const;
265 
270  bool isContextual() const { return mIsContextual; }
271 
277  virtual bool isDeprecated() const;
278 
283  QString group() const { return mGroups.isEmpty() ? QString() : mGroups.at( 0 ); }
284 
290  QStringList groups() const { return mGroups; }
291 
293  const QString helpText() const;
294 
303  virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) = 0;
304 
309  virtual QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node );
310 
311  bool operator==( const QgsExpressionFunction &other ) const;
312 
317  virtual bool handlesNull() const;
318 
319  protected:
320 
330  static bool allParamsStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context );
331 
332  private:
333  QString mName;
334  int mParams;
336  QStringList mGroups;
337  QString mHelpText;
338  bool mLazyEval;
339  bool mHandlesNull;
340  bool mIsContextual; //if true function is only available through an expression context
341 };
342 
348 #ifndef SIP_RUN
350 {
351  public:
352 
356  QgsStaticExpressionFunction( const QString &fnname,
357  int params,
358  FcnEval fcn,
359  const QString &group,
360  const QString &helpText = QString(),
361  bool usesGeometry = false,
362  const QSet<QString> &referencedColumns = QSet<QString>(),
363  bool lazyEval = false,
364  const QStringList &aliases = QStringList(),
365  bool handlesNull = false )
367  , mFnc( fcn )
368  , mAliases( aliases )
369  , mUsesGeometry( usesGeometry )
370  , mReferencedColumns( referencedColumns )
371  {
372  }
373 
377  QgsStaticExpressionFunction( const QString &fnname,
379  FcnEval fcn,
380  const QString &group,
381  const QString &helpText = QString(),
382  bool usesGeometry = false,
383  const QSet<QString> &referencedColumns = QSet<QString>(),
384  bool lazyEval = false,
385  const QStringList &aliases = QStringList(),
386  bool handlesNull = false )
388  , mFnc( fcn )
389  , mAliases( aliases )
390  , mUsesGeometry( usesGeometry )
391  , mReferencedColumns( referencedColumns )
392  {}
393 
405  QgsStaticExpressionFunction( const QString &fnname,
407  FcnEval fcn,
408  const QString &group,
409  const QString &helpText,
410  const std::function< bool( const QgsExpressionNodeFunction *node )> &usesGeometry,
411  const std::function< QSet<QString>( const QgsExpressionNodeFunction *node )> &referencedColumns,
412  bool lazyEval = false,
413  const QStringList &aliases = QStringList(),
414  bool handlesNull = false );
415 
420  QgsStaticExpressionFunction( const QString &fnname,
422  FcnEval fcn,
423  const QStringList &groups,
424  const QString &helpText = QString(),
425  bool usesGeometry = false,
426  const QSet<QString> &referencedColumns = QSet<QString>(),
427  bool lazyEval = false,
428  const QStringList &aliases = QStringList(),
429  bool handlesNull = false )
431  , mFnc( fcn )
432  , mAliases( aliases )
433  , mUsesGeometry( usesGeometry )
434  , mReferencedColumns( referencedColumns )
435  {}
436 
445  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override
446  {
447  return mFnc ? mFnc( values, context, parent, node ) : QVariant();
448  }
449 
450  QStringList aliases() const override;
451 
452  bool usesGeometry( const QgsExpressionNodeFunction *node ) const override;
453 
454  QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const override;
455 
456  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
457 
458  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
459 
466  void setIsStaticFunction( const std::function< bool ( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) > &isStatic );
467 
475  void setIsStatic( bool isStatic );
476 
483  void setPrepareFunction( const std::function< bool( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * )> &prepareFunc );
484 
488  static const QList<QgsExpressionFunction *> &functions();
489 
490  private:
491  FcnEval mFnc;
492  QStringList mAliases;
493  bool mUsesGeometry;
494  std::function < bool( const QgsExpressionNodeFunction *node ) > mUsesGeometryFunc;
495  std::function < QSet<QString>( const QgsExpressionNodeFunction *node ) > mReferencedColumnsFunc;
496  std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mIsStaticFunc = allParamsStatic;
497  std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mPrepareFunc;
498  QSet<QString> mReferencedColumns;
499  bool mIsStatic = false;
500 };
501 
511 {
512  public:
514 
515  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
516 
517  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
518 
519  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
520 
521  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
522 
523 };
524 
534 {
535  public:
537 
538  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
539 
540  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
541 
542  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
543 
544  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
545 
546 };
547 
558 {
559  public:
561 
562  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
563 
564  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
565 
566  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
567 
568  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
569 
570  private:
571 
575  void appendTemporaryVariable( const QgsExpressionContext *context, const QString &name, const QVariant &value ) const;
576 
580  void popTemporaryVariable( const QgsExpressionContext *context ) const;
581 };
582 
583 #endif
584 
585 #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_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.
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 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)