QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 
378  QgsStaticExpressionFunction( const QString &fnname,
379  int params,
380  FcnEval fcn,
381  const QStringList &groups,
382  const QString &helpText = QString(),
383  bool usesGeometry = false,
384  const QSet<QString> &referencedColumns = QSet<QString>(),
385  bool lazyEval = false,
386  const QStringList &aliases = QStringList(),
387  bool handlesNull = false )
389  , mFnc( fcn )
390  , mAliases( aliases )
391  , mUsesGeometry( usesGeometry )
392  , mReferencedColumns( referencedColumns )
393  {
394  }
395 
399  QgsStaticExpressionFunction( const QString &fnname,
401  FcnEval fcn,
402  const QString &group,
403  const QString &helpText = QString(),
404  bool usesGeometry = false,
405  const QSet<QString> &referencedColumns = QSet<QString>(),
406  bool lazyEval = false,
407  const QStringList &aliases = QStringList(),
408  bool handlesNull = false )
410  , mFnc( fcn )
411  , mAliases( aliases )
412  , mUsesGeometry( usesGeometry )
413  , mReferencedColumns( referencedColumns )
414  {}
415 
427  QgsStaticExpressionFunction( const QString &fnname,
429  FcnEval fcn,
430  const QString &group,
431  const QString &helpText,
432  const std::function< bool( const QgsExpressionNodeFunction *node )> &usesGeometry,
433  const std::function< QSet<QString>( const QgsExpressionNodeFunction *node )> &referencedColumns,
434  bool lazyEval = false,
435  const QStringList &aliases = QStringList(),
436  bool handlesNull = false );
437 
442  QgsStaticExpressionFunction( const QString &fnname,
444  FcnEval fcn,
445  const QStringList &groups,
446  const QString &helpText = QString(),
447  bool usesGeometry = false,
448  const QSet<QString> &referencedColumns = QSet<QString>(),
449  bool lazyEval = false,
450  const QStringList &aliases = QStringList(),
451  bool handlesNull = false )
453  , mFnc( fcn )
454  , mAliases( aliases )
455  , mUsesGeometry( usesGeometry )
456  , mReferencedColumns( referencedColumns )
457  {}
458 
467  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override
468  {
469  return mFnc ? mFnc( values, context, parent, node ) : QVariant();
470  }
471 
472  QStringList aliases() const override;
473 
474  bool usesGeometry( const QgsExpressionNodeFunction *node ) const override;
475 
476  QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const override;
477 
478  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
479 
480  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
481 
488  void setIsStaticFunction( const std::function< bool ( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) > &isStatic );
489 
497  void setIsStatic( bool isStatic );
498 
505  void setPrepareFunction( const std::function< bool( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * )> &prepareFunc );
506 
510  static const QList<QgsExpressionFunction *> &functions();
511 
512  private:
513  FcnEval mFnc;
514  QStringList mAliases;
515  bool mUsesGeometry;
516  std::function < bool( const QgsExpressionNodeFunction *node ) > mUsesGeometryFunc;
517  std::function < QSet<QString>( const QgsExpressionNodeFunction *node ) > mReferencedColumnsFunc;
518  std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mIsStaticFunc = allParamsStatic;
519  std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mPrepareFunc;
520  QSet<QString> mReferencedColumns;
521  bool mIsStatic = false;
522 };
523 
533 {
534  public:
536 
537  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
538 
539  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
540 
541  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
542 
543  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
544 
545 };
546 
556 {
557  public:
559 
560  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
561 
562  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
563 
564  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
565 
566  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
567 
568 };
569 
580 {
581  public:
583 
584  bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
585 
586  QVariant run( QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
587 
588  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node ) override;
589 
590  bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
591 
592  private:
593 
597  void appendTemporaryVariable( const QgsExpressionContext *context, const QString &name, const QVariant &value ) const;
598 
602  void popTemporaryVariable( const QgsExpressionContext *context ) const;
603 };
604 
605 #endif
606 
607 #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.
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)