Skip to content

Commit 607b1df

Browse files
committedJun 10, 2016
Fix joined attributes can't be used in filter expressions
(fix #13176)
1 parent 12bb1f7 commit 607b1df

File tree

2 files changed

+55
-7
lines changed

2 files changed

+55
-7
lines changed
 

‎src/core/qgsvectorlayerfeatureiterator.cpp

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

98115
mHasVirtualAttributes = !mFetchJoinInfo.isEmpty() || !mExpressionFieldInfo.isEmpty();
@@ -173,12 +190,6 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
173190

174191
rewindEditBuffer();
175192
}
176-
177-
if ( mRequest.filterType() == QgsFeatureRequest::FilterExpression )
178-
{
179-
mRequest.expressionContext()->setFields( mSource->mFields );
180-
mRequest.filterExpression()->prepare( mRequest.expressionContext() );
181-
}
182193
}
183194

184195

‎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().setFlags(QgsFeatureRequest.SubsetOfAttributes).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)
Please sign in to comment.