Skip to content

Commit 8031ac4

Browse files
committed
Expression variables are more often than not static
1 parent 1711a41 commit 8031ac4

File tree

3 files changed

+89
-7
lines changed

3 files changed

+89
-7
lines changed

python/core/qgsexpression.sip

+5
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,11 @@ Does this function use a geometry object.
574574
:rtype: bool
575575
%End
576576

577+
virtual bool isStatic( const QgsExpression::NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
578+
%Docstring
579+
:rtype: bool
580+
%End
581+
577582
virtual QSet<QString> referencedColumns( const QgsExpression::NodeFunction *node ) const;
578583
%Docstring
579584
Returns a set of field names which are required for this function.

src/core/qgsexpression.cpp

+53-7
Original file line numberDiff line numberDiff line change
@@ -4212,9 +4212,29 @@ const QList<QgsExpression::Function *> &QgsExpression::Functions()
42124212
<< new StaticFunction( QStringLiteral( "layer_property" ), 2, fcnGetLayerProperty, QStringLiteral( "General" ) )
42134213
<< new StaticFunction( QStringLiteral( "raster_statistic" ), ParameterList() << Parameter( QStringLiteral( "layer" ) )
42144214
<< Parameter( QStringLiteral( "band" ) )
4215-
<< Parameter( QStringLiteral( "statistic" ) ), fcnGetRasterBandStat, QStringLiteral( "General" ) )
4216-
<< new StaticFunction( QStringLiteral( "var" ), 1, fcnGetVariable, QStringLiteral( "General" ) )
4215+
<< Parameter( QStringLiteral( "statistic" ) ), fcnGetRasterBandStat, QStringLiteral( "General" ) );
42174216

4217+
// **var** function
4218+
StaticFunction *varFunction = new StaticFunction( QStringLiteral( "var" ), 1, fcnGetVariable, QStringLiteral( "General" ) );
4219+
varFunction->setIsStaticFunction(
4220+
[]( const NodeFunction * node, QgsExpression * parent, const QgsExpressionContext * context )
4221+
{
4222+
if ( node->args()->count() > 0 )
4223+
{
4224+
Node *argNode = node->args()->at( 0 );
4225+
4226+
if ( !argNode->isStatic( parent, context ) )
4227+
return false;
4228+
4229+
if ( fcnGetVariable( QVariantList() << argNode->eval( parent, context ), context, parent ).isValid() )
4230+
return true;
4231+
}
4232+
return false;
4233+
}
4234+
);
4235+
4236+
sFunctions
4237+
<< varFunction
42184238
//return all attributes string for referencedColumns - this is caught by
42194239
// QgsFeatureRequest::setSubsetOfAttributes and causes all attributes to be fetched by the
42204240
// feature request
@@ -5590,10 +5610,7 @@ QgsExpression::Node *QgsExpression::NodeFunction::clone() const
55905610

55915611
bool QgsExpression::NodeFunction::isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const
55925612
{
5593-
Q_UNUSED( parent )
5594-
Q_UNUSED( context )
5595-
// TODO some functions are static!
5596-
return false;
5613+
return Functions()[mFnIndex]->isStatic( this, parent, context );
55975614
}
55985615

55995616
bool QgsExpression::NodeFunction::validateParams( int fnIndex, QgsExpression::NodeList *args, QString &error )
@@ -6299,6 +6316,14 @@ bool QgsExpression::Function::usesGeometry( const QgsExpression::NodeFunction *n
62996316
return true;
63006317
}
63016318

6319+
bool QgsExpression::Function::isStatic( const QgsExpression::NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const
6320+
{
6321+
Q_UNUSED( parent )
6322+
Q_UNUSED( context )
6323+
Q_UNUSED( node )
6324+
return false;
6325+
}
6326+
63026327
QSet<QString> QgsExpression::Function::referencedColumns( const NodeFunction *node ) const
63036328
{
63046329
Q_UNUSED( node )
@@ -6310,7 +6335,15 @@ bool QgsExpression::Function::operator==( const QgsExpression::Function &other )
63106335
return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
63116336
}
63126337

6313-
QgsExpression::StaticFunction::StaticFunction( const QString &fnname, const QgsExpression::ParameterList &params, QgsExpression::FcnEval fcn, const QString &group, const QString &helpText, std::function < bool ( const QgsExpression::NodeFunction *node ) > usesGeometry, std::function < QSet<QString>( const QgsExpression::NodeFunction *node ) > referencedColumns, bool lazyEval, const QStringList &aliases, bool handlesNull )
6338+
QgsExpression::StaticFunction::StaticFunction( const QString &fnname, const QgsExpression::ParameterList &params,
6339+
QgsExpression::FcnEval fcn,
6340+
const QString &group,
6341+
const QString &helpText,
6342+
std::function < bool ( const QgsExpression::NodeFunction *node ) > usesGeometry,
6343+
std::function < QSet<QString>( const QgsExpression::NodeFunction *node ) > referencedColumns,
6344+
bool lazyEval,
6345+
const QStringList &aliases,
6346+
bool handlesNull )
63146347
: Function( fnname, params, group, helpText, lazyEval, handlesNull )
63156348
, mFnc( fcn )
63166349
, mAliases( aliases )
@@ -6336,6 +6369,19 @@ QSet<QString> QgsExpression::StaticFunction::referencedColumns( const NodeFuncti
63366369
return mReferencedColumns;
63376370
}
63386371

6372+
bool QgsExpression::StaticFunction::isStatic( const NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const
6373+
{
6374+
if ( mIsStaticFunc )
6375+
return mIsStaticFunc( node, parent, context );
6376+
else
6377+
return false;
6378+
}
6379+
6380+
void QgsExpression::StaticFunction::setIsStaticFunction( std::function<bool ( const NodeFunction *, QgsExpression *, const QgsExpressionContext * )> isStatic )
6381+
{
6382+
mIsStaticFunc = isStatic;
6383+
}
6384+
63396385
QVariant QgsExpression::Node::eval( QgsExpression *parent, const QgsExpressionContext *context )
63406386
{
63416387
if ( mHasCachedValue )

src/core/qgsexpression.h

+31
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,8 @@ class CORE_EXPORT QgsExpression
578578
* Functions are non lazy default and will be given the node return value when called **/
579579
bool lazyEval() const { return mLazyEval; }
580580

581+
virtual bool isStatic( const QgsExpression::NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
582+
581583
/**
582584
* Returns a set of field names which are required for this function.
583585
* May contain QgsFeatureRequest::AllAttributes to signal that all
@@ -705,6 +707,30 @@ class CORE_EXPORT QgsExpression
705707
const QStringList &aliases = QStringList(),
706708
bool handlesNull = false );
707709

710+
711+
/**
712+
* Static function for evaluation against a QgsExpressionContext, using a named list of parameter values.
713+
*
714+
* Lambda functions can be provided that will be called to determine if a geometry is used an which
715+
* columns are referenced.
716+
* This is only required if this cannot be determined by calling each parameter node's usesGeometry() or
717+
* referencedColumns() method. For example, an aggregate expression requires the geometry and all columns
718+
* if the parent variable is used.
719+
* If a nullptr is passed as a node to these functions, they should stay on the safe side and return if they
720+
* could potentially require a geometry or columns.
721+
*/
722+
StaticFunction( const QString &fnname,
723+
const QgsExpression::ParameterList &params,
724+
FcnEval fcn,
725+
const QString &group,
726+
const QString &helpText,
727+
std::function < bool ( const QgsExpression::NodeFunction *node ) > usesGeometry,
728+
std::function < QSet<QString>( const QgsExpression::NodeFunction *node ) > referencedColumns,
729+
std::function < bool( const NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > isStatic,
730+
bool lazyEval = false,
731+
const QStringList &aliases = QStringList(),
732+
bool handlesNull = false );
733+
708734
/** Static function for evaluation against a QgsExpressionContext, using a named list of parameter values and list
709735
* of groups.
710736
*/
@@ -742,12 +768,17 @@ class CORE_EXPORT QgsExpression
742768

743769
virtual QSet<QString> referencedColumns( const QgsExpression::NodeFunction *node ) const override;
744770

771+
virtual bool isStatic( const NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
772+
773+
void setIsStaticFunction( std::function < bool( const NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > isStatic );
774+
745775
private:
746776
FcnEval mFnc;
747777
QStringList mAliases;
748778
bool mUsesGeometry;
749779
std::function < bool( const QgsExpression::NodeFunction *node ) > mUsesGeometryFunc;
750780
std::function < QSet<QString>( const QgsExpression::NodeFunction *node ) > mReferencedColumnsFunc;
781+
std::function < bool( const NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mIsStaticFunc;
751782
QSet<QString> mReferencedColumns;
752783
};
753784
#endif

0 commit comments

Comments
 (0)