Skip to content

Commit acedb39

Browse files
committedJun 10, 2016
Fix joined attributes can't be used in filter expressions
(fix #13176)
1 parent 9a06144 commit acedb39

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed
 

‎src/core/qgsvectorlayerfeatureiterator.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
9393
, mFetchedFid( false )
9494
, mInterruptionChecker( nullptr )
9595
{
96+
//ensure that all fields required for filter expressions are prepared
97+
if ( mRequest.filterType() == QgsFeatureRequest::FilterExpression )
98+
{
99+
Q_FOREACH ( const QString& field, mRequest.filterExpression()->referencedColumns() )
100+
{
101+
int attrIdx = mSource->mFields.fieldNameIndex( field );
102+
if ( !mRequest.subsetOfAttributes().contains( attrIdx ) )
103+
mRequest.setSubsetOfAttributes( mRequest.subsetOfAttributes() << attrIdx );
104+
}
105+
}
106+
96107
prepareFields();
97108

98109
mHasVirtualAttributes = !mFetchJoinInfo.isEmpty() || !mExpressionFieldInfo.isEmpty();

‎tests/src/python/test_qgsfeatureiterator.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,44 @@ def test_JoinUsingExpression2(self):
239239
self.assertFalse(fi.nextFeature(f))
240240

241241
QgsMapLayerRegistry.instance().removeMapLayers([layer.id(), joinLayer.id()])
242-
# try the other way too
242+
243+
def test_JoinUsingFeatureRequestExpression(self):
244+
""" test requesting features using a filter expression which requires joined columns """
245+
joinLayer = QgsVectorLayer(
246+
"Point?field=x:string&field=y:integer&field=z:integer",
247+
"joinlayer", "memory")
248+
pr = joinLayer.dataProvider()
249+
f1 = QgsFeature()
250+
f1.setAttributes(["foo", 123, 321])
251+
f2 = QgsFeature()
252+
f2.setAttributes(["bar", 124, 654])
253+
self.assertTrue(pr.addFeatures([f1, f2]))
254+
255+
layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
256+
"addfeat", "memory")
257+
pr = layer.dataProvider()
258+
f1 = QgsFeature()
259+
f1.setAttributes(["test", 123])
260+
f2 = QgsFeature()
261+
f2.setAttributes(["test", 124])
262+
self.assertTrue(pr.addFeatures([f1, f2]))
263+
264+
QgsMapLayerRegistry.instance().addMapLayers([layer, joinLayer])
265+
266+
join = QgsVectorJoinInfo()
267+
join.targetFieldName = "fldint"
268+
join.joinLayerId = joinLayer.id()
269+
join.joinFieldName = "y"
270+
join.memoryCache = True
271+
layer.addJoin(join)
272+
273+
f = QgsFeature()
274+
fi = layer.getFeatures(QgsFeatureRequest().setFilterExpression('joinlayer_z=654'))
275+
self.assertTrue(fi.nextFeature(f))
276+
self.assertEqual(f['fldint'], 124)
277+
self.assertEqual(f['joinlayer_z'], 654)
278+
279+
QgsMapLayerRegistry.instance().removeMapLayers([layer.id(), joinLayer.id()])
243280

244281

245282
if __name__ == '__main__':

0 commit comments

Comments
 (0)