Skip to content
Permalink
Browse files

Fix aggregate expression calculation when used with virtual fields

The layer expression context (which is required for aggregate
calculation to work) was not being added to the context used
by vector layer feature iterators.

Fix #15930
  • Loading branch information
nyalldawson committed Jul 14, 2017
1 parent 0639264 commit 3f4d6de54b476176724877c5a490665fa3dcb9df
@@ -61,6 +61,7 @@ class QgsVectorLayerFeatureSource : QgsAbstractFeatureSource




};


@@ -79,6 +79,9 @@ QgsVectorLayerFeatureSource::QgsVectorLayerFeatureSource( const QgsVectorLayer *
}
#endif
}

std::unique_ptr< QgsExpressionContextScope > layerScope( QgsExpressionContextUtils::layerScope( layer ) );
mLayerScope = *layerScope;
}

QgsVectorLayerFeatureSource::~QgsVectorLayerFeatureSource()
@@ -644,7 +647,7 @@ void QgsVectorLayerFeatureIterator::prepareFields()
mExpressionContext.reset( new QgsExpressionContext() );
mExpressionContext->appendScope( QgsExpressionContextUtils::globalScope() );
mExpressionContext->appendScope( QgsExpressionContextUtils::projectScope( QgsProject::instance() ) );
mExpressionContext->setFields( mSource->mFields );
mExpressionContext->appendScope( new QgsExpressionContextScope( mSource->mLayerScope ) );

mFieldsToPrepare = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList();

@@ -84,6 +84,8 @@ class CORE_EXPORT QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource

QgsFields mFields;

QgsExpressionContextScope mLayerScope;

bool mHasEditBuffer;

// A deep-copy is only performed, if the original maps change
@@ -1829,6 +1829,27 @@ def testAggregate(self):
self.assertTrue(ok)
self.assertEqual(val, 'this is a test')

def testAggregateInVirtualField(self):
"""
Test aggregates in a virtual field
"""
layer = QgsVectorLayer("Point?field=fldint:integer", "layer", "memory")
pr = layer.dataProvider()

int_values = [4, 2, 3, 2, 5, None, 8]
features = []
for i in int_values:
f = QgsFeature()
f.setFields(layer.fields())
f.setAttributes([i])
features.append(f)
assert pr.addFeatures(features)

field = QgsField('virtual', QVariant.Double)
layer.addExpressionField('sum(fldint*2)', field)
vals = [f['virtual'] for f in layer.getFeatures()]
self.assertEqual(vals, [48, 48, 48, 48, 48, 48, 48])

def onLayerOpacityChanged(self, tr):
self.opacityTest = tr

0 comments on commit 3f4d6de

Please sign in to comment.
You can’t perform that action at this time.