Navigation Menu

Skip to content

Commit

Permalink
[ogr] Fix layer subset string is ignored when OGR refuses to accept
Browse files Browse the repository at this point in the history
a compiled feature request expression

Fixes #37073

(cherry picked from commit aa2d248)
  • Loading branch information
nyalldawson committed Jun 19, 2020
1 parent 3409567 commit eb63bb3
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/core/providers/ogr/qgsogrfeatureiterator.cpp
Expand Up @@ -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() )
{
Expand Down
25 changes: 25 additions & 0 deletions tests/src/python/test_provider_ogr.py
Expand Up @@ -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()
1 change: 1 addition & 0 deletions tests/testdata/filter_test.cpg
@@ -0,0 +1 @@
UTF-8
Binary file added tests/testdata/filter_test.dbf
Binary file not shown.
1 change: 1 addition & 0 deletions tests/testdata/filter_test.prj
@@ -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 added tests/testdata/filter_test.shp
Binary file not shown.
Binary file added tests/testdata/filter_test.shx
Binary file not shown.

0 comments on commit eb63bb3

Please sign in to comment.