Skip to content

Commit 7a05a7a

Browse files
committedOct 28, 2016
Fix caching of aggregate values with @parent
And add a test for referencedVariables
1 parent 8e25b89 commit 7a05a7a

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed
 

‎src/core/qgsexpression.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -682,8 +682,8 @@ static QVariant fcnAggregate( const QVariantList& values, const QgsExpressionCon
682682
{
683683
QString cacheKey = QStringLiteral( "aggfcn:%1:%2:%3:%4" ).arg( vl->id(), QString::number( aggregate ), subExpression, parameters.filter );
684684

685-
QgsExpression subExp( subExpression );
686-
if ( subExp.referencedVariables().contains( "parent" ) || subExp.referencedVariables().contains( QString() ) )
685+
QgsExpression filterExp( parameters.filter );
686+
if ( filterExp.referencedVariables().contains( "parent" ) || filterExp.referencedVariables().contains( QString() ) )
687687
{
688688
cacheKey += ':' + qHash( context->feature() );
689689
}
@@ -5106,7 +5106,19 @@ QSet<QString> QgsExpression::NodeFunction::referencedVariables() const
51065106
return QSet<QString>() << QString();
51075107
}
51085108
else
5109-
return QSet<QString>();
5109+
{
5110+
QSet<QString> functionVariables = QSet<QString>();
5111+
5112+
if ( !mArgs )
5113+
return functionVariables;
5114+
5115+
Q_FOREACH ( Node* n, mArgs->list() )
5116+
{
5117+
functionVariables.unite( n->referencedVariables() );
5118+
}
5119+
5120+
return functionVariables;
5121+
}
51105122
}
51115123

51125124
bool QgsExpression::NodeFunction::needsGeometry() const

‎tests/src/core/testqgsexpression.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,17 @@ class TestQgsExpression: public QObject
15711571
QCOMPARE( refColsSet, expectedCols );
15721572
}
15731573

1574+
void referenced_variables()
1575+
{
1576+
QSet<QString> expectedVars;
1577+
expectedVars << QStringLiteral( "foo" ) << QStringLiteral( "bar" ) << QStringLiteral( "ppp" ) << QStringLiteral( "qqq" ) << QStringLiteral( "rrr" );
1578+
QgsExpression exp( QStringLiteral( "CASE WHEN intersects(@bar, $geometry) THEN @ppp ELSE @qqq * @rrr END + @foo IN (1, 2, 3)" ) );
1579+
QCOMPARE( exp.hasParserError(), false );
1580+
QSet<QString> refVar = exp.referencedVariables();
1581+
1582+
QCOMPARE( refVar, expectedVars );
1583+
}
1584+
15741585
void referenced_columns_all_attributes()
15751586
{
15761587
QgsExpression exp( QStringLiteral( "attribute($currentfeature,'test')" ) );

1 commit comments

Comments
 (1)

nirvn commented on Oct 31, 2016

@nirvn
Contributor

@m-kuhn , we're getting there! 😉 @parent is now properly updated as the code iterates through features. However, "FIELD" values (in the filter parameter expression) aren't updated when iterating through features, breaking stuff like aggregate('my_layer','count',$id,"my_layer_field" = attribute(@parent,"my_parent_field")).

Here's an updated test project (http://hub.qgis.org/attachments/10505/parent_v2.zip) which should help narrow things down. The test project labels two polygons using three aggregate calls. The third one is built on a "field" = attribute(@parent,"parent_field) which fails for the 2nd polygon. The failure is due to "field" not being updated with the 2nd polygon's values.

Screenshot:
lost

Please sign in to comment.