Skip to content

Commit 16d8da3

Browse files
committed
Fix some providers did not respect layer's subset when calculating
min/max/uniqueValues Providers included delimited text, memory, virtual layer, and WFS Add unit test to provider test
1 parent 483eb86 commit 16d8da3

File tree

6 files changed

+87
-0
lines changed

6 files changed

+87
-0
lines changed

src/providers/delimitedtext/qgsdelimitedtextprovider.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,7 @@ bool QgsDelimitedTextProvider::setSubsetString( const QString& subset, bool upda
10781078
}
10791079
}
10801080

1081+
mCacheMinMaxDirty = true;
10811082
emit dataChanged();
10821083
return valid;
10831084
}

src/providers/memory/qgsmemoryprovider.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ bool QgsMemoryProvider::setSubsetString( const QString& theSQL, bool updateFeatu
481481
}
482482

483483
mSubsetString = theSQL;
484+
mCacheMinMaxDirty = true;
484485

485486
emit dataChanged();
486487
return true;

src/providers/virtual/qgsvirtuallayerprovider.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ QString QgsVirtualLayerProvider::subsetString()
493493
bool QgsVirtualLayerProvider::setSubsetString( const QString& subset, bool updateFeatureCount )
494494
{
495495
mSubset = subset;
496+
mCacheMinMaxDirty = true;
496497
if ( updateFeatureCount )
497498
updateStatistics();
498499
return true;

src/providers/wfs/qgswfsprovider.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ QString QgsWFSProvider::subsetString()
130130
bool QgsWFSProvider::setSubsetString( const QString& theSQL, bool updateFeatureCount )
131131
{
132132
mSubsetString = theSQL;
133+
mCacheMinMaxDirty = true;
133134

134135
// update URI
135136
mShared->mURI.setFilter( theSQL );

tests/src/python/providertestbase.py

+22
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ def getSubsetString(self):
165165
"""Individual providers may need to override this depending on their subset string formats"""
166166
return '"cnt" > 100 and "cnt" < 410'
167167

168+
def getSubsetString2(self):
169+
"""Individual providers may need to override this depending on their subset string formats"""
170+
return '"cnt" > 100 and "cnt" < 400'
171+
168172
def testOrderByUncompiled(self):
169173
try:
170174
self.disableCompiler()
@@ -359,10 +363,22 @@ def testMinValue(self):
359363
self.assertEqual(self.provider.minimumValue(1), -200)
360364
self.assertEqual(self.provider.minimumValue(2), 'Apple')
361365

366+
subset = self.getSubsetString()
367+
self.provider.setSubsetString(subset)
368+
min_value = self.provider.minimumValue(1)
369+
self.provider.setSubsetString(None)
370+
self.assertEqual(min_value, 200)
371+
362372
def testMaxValue(self):
363373
self.assertEqual(self.provider.maximumValue(1), 400)
364374
self.assertEqual(self.provider.maximumValue(2), 'Pear')
365375

376+
subset = self.getSubsetString2()
377+
self.provider.setSubsetString(subset)
378+
max_value = self.provider.maximumValue(1)
379+
self.provider.setSubsetString(None)
380+
self.assertEqual(max_value, 300)
381+
366382
def testExtent(self):
367383
reference = QgsGeometry.fromRect(
368384
QgsRectangle(-71.123, 66.33, -65.32, 78.3))
@@ -374,6 +390,12 @@ def testUnique(self):
374390
self.assertEqual(set(self.provider.uniqueValues(1)), set([-200, 100, 200, 300, 400]))
375391
assert set([u'Apple', u'Honey', u'Orange', u'Pear', NULL]) == set(self.provider.uniqueValues(2)), 'Got {}'.format(set(self.provider.uniqueValues(2)))
376392

393+
subset = self.getSubsetString2()
394+
self.provider.setSubsetString(subset)
395+
values = self.provider.uniqueValues(1)
396+
self.provider.setSubsetString(None)
397+
self.assertEqual(set(values), set([200, 300]))
398+
377399
def testFeatureCount(self):
378400
assert self.provider.featureCount() == 5, 'Got {}'.format(self.provider.featureCount())
379401

tests/src/python/test_provider_wfs.py

+61
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,67 @@ def setUpClass(cls):
228228
</wfs:member>
229229
</wfs:FeatureCollection>""")
230230

231+
with open(sanitize(endpoint, """?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&FILTER=<fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0">
232+
<fes:And>
233+
<fes:PropertyIsGreaterThan>
234+
<fes:ValueReference>cnt</fes:ValueReference>
235+
<fes:Literal>100</fes:Literal>
236+
</fes:PropertyIsGreaterThan>
237+
<fes:PropertyIsLessThan>
238+
<fes:ValueReference>cnt</fes:ValueReference>
239+
<fes:Literal>400</fes:Literal>
240+
</fes:PropertyIsLessThan>
241+
</fes:And>
242+
</fes:Filter>
243+
&RESULTTYPE=hits"""), 'wb') as f:
244+
f.write("""
245+
<wfs:FeatureCollection
246+
xmlns:wfs="http://www.opengis.net/wfs/2.0"
247+
xmlns:gml="http://www.opengis.net/gml/3.2"
248+
numberMatched="2" numberReturned="0" timeStamp="2016-03-25T14:51:48.998Z">
249+
</wfs:FeatureCollection>""")
250+
251+
with open(sanitize(endpoint, """?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&SRSNAME=urn:ogc:def:crs:EPSG::4326&FILTER=<fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0">
252+
<fes:And>
253+
<fes:PropertyIsGreaterThan>
254+
<fes:ValueReference>cnt</fes:ValueReference>
255+
<fes:Literal>100</fes:Literal>
256+
</fes:PropertyIsGreaterThan>
257+
<fes:PropertyIsLessThan>
258+
<fes:ValueReference>cnt</fes:ValueReference>
259+
<fes:Literal>400</fes:Literal>
260+
</fes:PropertyIsLessThan>
261+
</fes:And>
262+
</fes:Filter>
263+
"""), 'wb') as f:
264+
f.write("""
265+
<wfs:FeatureCollection
266+
xmlns:wfs="http://www.opengis.net/wfs/2.0"
267+
xmlns:gml="http://www.opengis.net/gml/3.2"
268+
xmlns:my="http://my"
269+
numberMatched="2" numberReturned="2" timeStamp="2016-03-25T14:51:48.998Z">
270+
<wfs:member>
271+
<my:typename gml:id="typename.1">
272+
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>70.8 -68.2</gml:lowerCorner><gml:upperCorner>70.8 -68.2</gml:upperCorner></gml:Envelope></gml:boundedBy>
273+
<my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326" gml:id="typename.geom.1"><gml:pos>70.8 -68.2</gml:pos></gml:Point></my:geometryProperty>
274+
<my:pk>2</my:pk>
275+
<my:cnt>200</my:cnt>
276+
<my:name>Apple</my:name>
277+
<my:name2>Apple</my:name2>
278+
<my:num_char>2</my:num_char>
279+
</my:typename>
280+
</wfs:member>
281+
<wfs:member>
282+
<my:typename gml:id="typename.3">
283+
<my:pk>3</my:pk>
284+
<my:cnt>300</my:cnt>
285+
<my:name>Pear</my:name>
286+
<my:name2>PEaR</my:name2>
287+
<my:num_char>3</my:num_char>
288+
</my:typename>
289+
</wfs:member>
290+
</wfs:FeatureCollection>""")
291+
231292
@classmethod
232293
def tearDownClass(cls):
233294
"""Run after all tests"""

0 commit comments

Comments
 (0)