Skip to content

Commit

Permalink
Fix vector iterator number of attributes returned with virtual fields
Browse files Browse the repository at this point in the history
Fix the issue of wrong number of attributes returned when the feature
request has setSubsetOfAttributes set, in that case the virtual fields
were not returned causing an inconsistency in the API response.

With this patch the virtual fields are always returned (possibly Null).
  • Loading branch information
elpaso authored and nyalldawson committed May 15, 2023
1 parent 8d64197 commit 9993f33
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/core/vector/qgsvectorlayerfeatureiterator.cpp
Expand Up @@ -551,6 +551,8 @@ bool QgsVectorLayerFeatureIterator::fetchFeature( QgsFeature &f )

if ( mHasVirtualAttributes )
addVirtualAttributes( f );
else
f.padAttributes( mSource->mFields.count() - f.attributeCount() );

if ( mRequest.filterType() == QgsFeatureRequest::FilterExpression && mProviderRequest.filterType() != QgsFeatureRequest::FilterExpression )
{
Expand Down Expand Up @@ -664,6 +666,8 @@ void QgsVectorLayerFeatureIterator::useAddedFeature( const QgsFeature &src, QgsF

if ( mHasVirtualAttributes )
addVirtualAttributes( f );
else
f.padAttributes( mSource->mFields.count() - f.attributeCount() );
}


Expand Down Expand Up @@ -918,6 +922,7 @@ void QgsVectorLayerFeatureIterator::prepareFields()
{
createOrderedJoinList();
}

}

void QgsVectorLayerFeatureIterator::createOrderedJoinList()
Expand Down Expand Up @@ -1292,6 +1297,8 @@ bool QgsVectorLayerFeatureIterator::nextFeatureFid( QgsFeature &f )

if ( mHasVirtualAttributes )
addVirtualAttributes( f );
else
f.padAttributes( mSource->mFields.count() - f.attributeCount() );

return true;
}
Expand Down
28 changes: 28 additions & 0 deletions tests/src/python/test_qgsvectorlayer.py
Expand Up @@ -2658,6 +2658,34 @@ def testReselect(self):
layer.reselect()
self.assertCountEqual(layer.selectedFeatureIds(), [5])

def testGetFeaturesVirtualFieldsSubset(self):
"""Test that when a subset is requested virtual fields are returned nullified"""

vl = QgsVectorLayer(os.path.join(unitTestDataPath(), 'points.shp'), 'Points', 'ogr')
virt_field_idx = vl.addExpressionField('\'Importance: \' || Importance', QgsField('virt_1', QVariant.String))

self.assertEqual(vl.fields().lookupField('virt_1'), virt_field_idx)

req = QgsFeatureRequest()
req.setSubsetOfAttributes([0, 1])
attrs = next(vl.getFeatures(req)).attributes()
self.assertEqual(attrs, ['Jet', 90, None, None, None, None, None])

attrs = next(vl.getFeatures()).attributes()
self.assertEqual(attrs, ['Jet', 90, 3.0, 2, 0, 2, 'Importance: 3'])

req.setSubsetOfAttributes([0, 2])
attrs = next(vl.getFeatures(req)).attributes()
self.assertEqual(attrs, ['Jet', None, 3.0, None, None, None, None])

req.setSubsetOfAttributes([0, 1, 6])
attrs = next(vl.getFeatures(req)).attributes()
self.assertEqual(attrs, ['Jet', 90, 3.0, None, None, None, 'Importance: 3'])

req.setSubsetOfAttributes([6])
attrs = next(vl.getFeatures(req)).attributes()
self.assertEqual(attrs, [None, None, 3.0, None, None, None, 'Importance: 3'])

def testAggregate(self):
""" Test aggregate calculation """
layer = QgsVectorLayer("Point?field=fldint:integer", "layer", "memory")
Expand Down

0 comments on commit 9993f33

Please sign in to comment.