Skip to content

Commit 6d71053

Browse files
committed
Fix feature request containing a filter expression which needs
both geometry and the magic all attributes flag (cherry picked from commit 33aa63b)
1 parent 86b0bd8 commit 6d71053

File tree

4 files changed

+47
-0
lines changed

4 files changed

+47
-0
lines changed

src/core/qgsvectorlayerfeatureiterator.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
199199

200200
if ( mProviderRequest.filterType() == QgsFeatureRequest::FilterExpression )
201201
{
202+
const bool needsGeom = mProviderRequest.filterExpression()->needsGeometry();
202203
Q_FOREACH ( const QString &field, mProviderRequest.filterExpression()->referencedColumns() )
203204
{
204205
int idx = source->mFields.lookupField( field );
@@ -210,6 +211,12 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
210211
mProviderRequest.disableFilter();
211212
// can't limit at provider side
212213
mProviderRequest.setLimit( -1 );
214+
if ( needsGeom )
215+
{
216+
// have to get geometry from provider in order to evaluate expression on client
217+
mProviderRequest.setFlags( mProviderRequest.flags() & ~QgsFeatureRequest::NoGeometry );
218+
}
219+
break;
213220
}
214221
}
215222
}

tests/src/python/featuresourcetestbase.py

+16
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,22 @@ def testRectAndExpression(self):
528528
for f in self.source.getFeatures():
529529
self.assertEqual(request.acceptFeature(f), f['pk'] in expected)
530530

531+
def testGeomAndAllAttributes(self):
532+
"""
533+
Test combination of a filter which requires geometry and all attributes
534+
"""
535+
request = QgsFeatureRequest().setFilterExpression('attribute($currentfeature,\'cnt\')>200 and $x>=-70 and $x<=-60').setSubsetOfAttributes([]).setFlags(QgsFeatureRequest.NoGeometry)
536+
result = set([f['pk'] for f in self.source.getFeatures(request)])
537+
all_valid = (all(f.isValid() for f in self.source.getFeatures(request)))
538+
self.assertEqual(result, {4})
539+
self.assertTrue(all_valid)
540+
541+
request = QgsFeatureRequest().setFilterExpression('attribute($currentfeature,\'cnt\')>200 and $x>=-70 and $x<=-60')
542+
result = set([f['pk'] for f in self.source.getFeatures(request)])
543+
all_valid = (all(f.isValid() for f in self.source.getFeatures(request)))
544+
self.assertEqual(result, {4})
545+
self.assertTrue(all_valid)
546+
531547
def testRectAndFids(self):
532548
"""
533549
Test the combination of a filter rect along with filterfids

tests/src/python/test_provider_wfs.py

+3
Original file line numberDiff line numberDiff line change
@@ -3857,6 +3857,9 @@ def test_NullValues_regression_20961(self):
38573857
self.assertEqual(str(got_f2[1]['elevation']), 'NULL')
38583858
self.assertEqual(str(got_f2[1]['name']), 'sdf')
38593859

3860+
def testGeomAndAllAttributes(self):
3861+
pass # skip this feature source test -- provider is not affected
3862+
38603863
def testFilteredFeatureRequests(self):
38613864
"""Test https://issues.qgis.org/issues/21077 """
38623865

tests/src/python/test_qgsvectorlayer.py

+21
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666
from featuresourcetestbase import FeatureSourceTestCase
6767
from utilities import unitTestDataPath
6868

69+
TEST_DATA_DIR = unitTestDataPath()
70+
6971
start_app()
7072

7173

@@ -184,6 +186,25 @@ def dumpEditBuffer(layer):
184186
print(("%d | %s" % (f.id(), f.geometry().asWkt())))
185187

186188

189+
class TestQgsVectorLayerShapefile(unittest.TestCase, FeatureSourceTestCase):
190+
191+
"""
192+
Tests a vector layer against the feature source tests, using a real layer source (not a memory layer)
193+
"""
194+
@classmethod
195+
def getSource(cls):
196+
vl = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'provider', 'shapefile.shp'), 'test')
197+
assert (vl.isValid())
198+
return vl
199+
200+
@classmethod
201+
def setUpClass(cls):
202+
"""Run before all tests"""
203+
QgsGui.editorWidgetRegistry().initEditors()
204+
# Create test layer for FeatureSourceTestCase
205+
cls.source = cls.getSource()
206+
207+
187208
class TestQgsVectorLayer(unittest.TestCase, FeatureSourceTestCase):
188209

189210
@classmethod

0 commit comments

Comments
 (0)