Skip to content
Permalink
Browse files

[ogr] Fix layer subset string is ignored when OGR refuses to accept

a compiled feature request expression

Fixes #37073

(cherry picked from commit aa2d248)
  • Loading branch information
nyalldawson committed Jun 10, 2020
1 parent 3409567 commit eb63bb37d88006c7f9ee93d207e4ada4e5dd8200
@@ -207,6 +207,11 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource *source, bool
mExpressionCompiled = ( result == QgsSqlExpressionCompiler::Complete );
mCompileStatus = ( mExpressionCompiled ? Compiled : PartiallyCompiled );
}
else if ( !mSource->mSubsetString.isEmpty() )
{
// OGR rejected the compiled expression. Make sure we restore the original subset string if set (and do the filtering on QGIS' side)
OGR_L_SetAttributeFilter( mOgrLayer, mSource->mEncoding->fromUnicode( mSource->mSubsetString ).constData() );
}
}
else if ( mSource->mSubsetString.isEmpty() )
{
@@ -687,6 +687,31 @@ def testSpatialiteDefaultValues(self):
self.assertEqual(feature.attribute(4), 123)
self.assertEqual(feature.attribute(5), 'My default')

def testMixOfFilterExpressionAndSubsetStringWhenFilterExpressionCompilationFails(self):
datasource = os.path.join(unitTestDataPath(), 'filter_test.shp')
vl = QgsVectorLayer(datasource, 'test', 'ogr')
self.assertTrue(vl.isValid())

self.assertCountEqual([f.attributes() for f in vl.getFeatures()], [['circle', '1'],
['circle', '2'],
['rectangle', '1'],
['rectangle', '2']])

# note - request uses wrong type for match (string vs int). This is OK for QGIS expressions,
# but will be rejected after we try to compile the expression for OGR to use.
request = QgsFeatureRequest().setFilterExpression('"color" = 1')
self.assertCountEqual([f.attributes() for f in vl.getFeatures(request)], [['circle', '1'],
['rectangle', '1']])
request = QgsFeatureRequest().setFilterExpression('"color" = 1')
self.assertCountEqual([f.attributes() for f in vl.getFeatures(request)], [['circle', '1'],
['rectangle', '1']])

vl.setSubsetString("\"shape\" = 'rectangle'")
self.assertCountEqual([f.attributes() for f in vl.getFeatures()], [['rectangle', '1'],
['rectangle', '2']])

self.assertCountEqual([f.attributes() for f in vl.getFeatures(request)], [['rectangle', '1']])


if __name__ == '__main__':
unittest.main()
@@ -0,0 +1 @@
UTF-8
Binary file not shown.
@@ -0,0 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
Binary file not shown.
Binary file not shown.

0 comments on commit eb63bb3

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