Skip to content

Commit

Permalink
[expression] Fix eval_template() not working with field caltulator an…
Browse files Browse the repository at this point in the history
…d virtual fields
  • Loading branch information
nirvn committed Aug 27, 2024
1 parent 450966f commit 489b66c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
23 changes: 22 additions & 1 deletion src/core/expression/qgsexpressionfunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9148,7 +9148,28 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
functions
<< varFunction;

functions << new QgsStaticExpressionFunction( QStringLiteral( "eval_template" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "template" ) ), fcnEvalTemplate, QStringLiteral( "General" ), QString(), true );
QgsStaticExpressionFunction *evalTemplateFunction = new QgsStaticExpressionFunction( QStringLiteral( "eval_template" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "template" ) ), fcnEvalTemplate, QStringLiteral( "General" ), QString(), true, QSet<QString>() << QgsFeatureRequest::ALL_ATTRIBUTES );
evalTemplateFunction->setIsStaticFunction(
[]( const QgsExpressionNodeFunction * node, QgsExpression * parent, const QgsExpressionContext * context )
{
if ( node->args()->count() > 0 )
{
QgsExpressionNode *argNode = node->args()->at( 0 );

if ( argNode->isStatic( parent, context ) )
{
QString expString = argNode->eval( parent, context ).toString();

QgsExpression e( expString );

if ( e.rootNode() && e.rootNode()->isStatic( parent, context ) )
return true;
}
}

return false;
} );
functions << evalTemplateFunction;

QgsStaticExpressionFunction *evalFunc = new QgsStaticExpressionFunction( QStringLiteral( "eval" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "expression" ) ), fcnEval, QStringLiteral( "General" ), QString(), true, QSet<QString>() << QgsFeatureRequest::ALL_ATTRIBUTES );
evalFunc->setIsStaticFunction(
Expand Down
17 changes: 17 additions & 0 deletions tests/src/python/test_qgsexpression.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,23 @@ def testSuccessfulEvaluationReturnsNoEvalErrorString(self):
exp = QgsExpression("True is False") # the result does not matter
self.assertEqual(exp.evalErrorString(), "")

def testEvalTemplate(self):
layer = QgsVectorLayer("Point?field=a:int&field=b:string", "test eval-template", "memory")
context = layer.createExpressionContext()

expression = QgsExpression("eval_template('123 [% \"b\" %] 789')")
expression.prepare(context)
columns = expression.referencedColumns()

# Insure prepare has returned all attributes as referenced columns with feature-less context
self.assertTrue(QgsFeatureRequest.ALL_ATTRIBUTES in columns)

feature = QgsFeature(layer.fields())
feature.setAttributes([1, '456'])
context.setFeature(feature)

self.assertEqual(expression.evaluate(context), '123 456 789')

def testExceptionDuringEvalReturnsTraceback(self):
QgsExpression.registerFunction(self.raise_exception)
exp = QgsExpression('raise_exception()')
Expand Down

0 comments on commit 489b66c

Please sign in to comment.