QGIS API Documentation 3.27.0-Master (f261cc1f8b)
qgsexpressionfunction.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsexpressionfunction.h
3 -------------------
4 begin : May 2017
5 copyright : (C) 2017 Matthias Kuhn
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
32class QgsExpression;
35
40class 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
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.
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...
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.
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.
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=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.
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)