Skip to content
Permalink
Browse files

Fix feature request containing a filter expression which needs

both geometry and the magic all attributes flag
  • Loading branch information
nyalldawson committed Feb 20, 2019
1 parent b981c8a commit 33aa63b85515cf0cbff161e3f14b117550fd9bfe
@@ -200,6 +200,7 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat

if ( mProviderRequest.filterType() == QgsFeatureRequest::FilterExpression )
{
const bool needsGeom = mProviderRequest.filterExpression()->needsGeometry();
Q_FOREACH ( const QString &field, mProviderRequest.filterExpression()->referencedColumns() )
{
int idx = source->mFields.lookupField( field );
@@ -211,6 +212,12 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
mProviderRequest.disableFilter();
// can't limit at provider side
mProviderRequest.setLimit( -1 );
if ( needsGeom )
{
// have to get geometry from provider in order to evaluate expression on client
mProviderRequest.setFlags( mProviderRequest.flags() & ~QgsFeatureRequest::NoGeometry );
}
break;
}
}
}
@@ -528,6 +528,22 @@ def testRectAndExpression(self):
for f in self.source.getFeatures():
self.assertEqual(request.acceptFeature(f), f['pk'] in expected)

def testGeomAndAllAttributes(self):
"""
Test combination of a filter which requires geometry and all attributes
"""
request = QgsFeatureRequest().setFilterExpression('attribute($currentfeature,\'cnt\')>200 and $x>=-70 and $x<=-60').setSubsetOfAttributes([]).setFlags(QgsFeatureRequest.NoGeometry)
result = set([f['pk'] for f in self.source.getFeatures(request)])
all_valid = (all(f.isValid() for f in self.source.getFeatures(request)))
self.assertEqual(result, {4})
self.assertTrue(all_valid)

request = QgsFeatureRequest().setFilterExpression('attribute($currentfeature,\'cnt\')>200 and $x>=-70 and $x<=-60')
result = set([f['pk'] for f in self.source.getFeatures(request)])
all_valid = (all(f.isValid() for f in self.source.getFeatures(request)))
self.assertEqual(result, {4})
self.assertTrue(all_valid)

def testRectAndFids(self):
"""
Test the combination of a filter rect along with filterfids
@@ -3857,6 +3857,9 @@ def test_NullValues_regression_20961(self):
self.assertEqual(str(got_f2[1]['elevation']), 'NULL')
self.assertEqual(str(got_f2[1]['name']), 'sdf')

def testGeomAndAllAttributes(self):
pass # skip this feature source test -- provider is not affected

def testFilteredFeatureRequests(self):
"""Test https://issues.qgis.org/issues/21077 """

@@ -66,6 +66,8 @@
from featuresourcetestbase import FeatureSourceTestCase
from utilities import unitTestDataPath

TEST_DATA_DIR = unitTestDataPath()

start_app()


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


class TestQgsVectorLayerShapefile(unittest.TestCase, FeatureSourceTestCase):

"""
Tests a vector layer against the feature source tests, using a real layer source (not a memory layer)
"""
@classmethod
def getSource(cls):
vl = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'provider', 'shapefile.shp'), 'test')
assert (vl.isValid())
return vl

@classmethod
def setUpClass(cls):
"""Run before all tests"""
QgsGui.editorWidgetRegistry().initEditors()
# Create test layer for FeatureSourceTestCase
cls.source = cls.getSource()


class TestQgsVectorLayer(unittest.TestCase, FeatureSourceTestCase):

@classmethod

0 comments on commit 33aa63b

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