Skip to content

Commit

Permalink
Fix boolean filtering in QGIS expressions with WFS layers (#60075)
Browse files Browse the repository at this point in the history
PR #56369 introduced a regression for WFS layers, because stopping using
'false' and 'true' strings to compare with boolean fields in qgis
expressions, and forcing to use the keywords false and true, it
conflicted with the internal SQLite cache database of WFS layers.

This PR fixes it by storing internal boolean in SQLite cache database in
the right form compatible with QGIS internal functions (i.e. storing '0'
and '1' strings instead of 'true' and 'false' strings).
  • Loading branch information
Djedouas authored Jan 7, 2025
1 parent 8e7781d commit c45551b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/providers/wfs/qgsbackgroundcachedshareddata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,8 @@ void QgsBackgroundCachedSharedData::serializeFeatures( QVector<QgsFeatureUniqueI
}
cachedFeature.setAttribute( idx, stringValue );
}
else if ( mFields.at( i ).type() == QMetaType::Type::Bool ) // WFS boolean fields are stored as varchar in underlying cache sqlite database
cachedFeature.setAttribute( idx, QgsSqliteUtils::quotedValue( QVariant::fromValue( v.toBool() ) ) );
else if ( QgsWFSUtils::isCompatibleType( static_cast<QMetaType::Type>( v.userType() ), fieldType ) )
cachedFeature.setAttribute( idx, v );
else
Expand Down
29 changes: 29 additions & 0 deletions tests/src/python/test_provider_wfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6277,6 +6277,7 @@ def testFilteredFeatureRequests(self):
<element type="gml:MultiPointPropertyType" name="geometry" minOccurs="0" maxOccurs="1"/>
<element type="int" name="id"/>
<element type="string" name="name"/>
<element type="boolean" name="verified"/>
<element type="int" name="type" nillable="true"/>
<element type="decimal" name="elevation" nillable="true"/>
</sequence>
Expand Down Expand Up @@ -6313,6 +6314,7 @@ def testFilteredFeatureRequests(self):
</qgs:geometry>
<qgs:id>177</qgs:id>
<qgs:name>Xxx</qgs:name>
<qgs:verified>true</qgs:verified>
<qgs:elevation_source></qgs:elevation_source>
</qgs:points>
</gml:featureMember>
Expand Down Expand Up @@ -6344,6 +6346,7 @@ def testFilteredFeatureRequests(self):
</qgs:geometry>
<qgs:id>177</qgs:id>
<qgs:name>Xxx</qgs:name>
<qgs:verified>true</qgs:verified>
<qgs:type xsi:nil="true"></qgs:type>
<qgs:elevation xsi:nil="true"></qgs:elevation>
</qgs:points>
Expand All @@ -6367,6 +6370,7 @@ def testFilteredFeatureRequests(self):
</qgs:geometry>
<qgs:id>5</qgs:id>
<qgs:name>qgis</qgs:name>
<qgs:verified>false</qgs:verified>
<qgs:type>0</qgs:type>
<qgs:elevation xsi:nil="true"></qgs:elevation>
</qgs:points>
Expand Down Expand Up @@ -6412,6 +6416,31 @@ def testFilteredFeatureRequests(self):
self.assertEqual(qgis_feat["name"], "qgis")
self.assertEqual(other_feat["name"], "Xxx")

qgis_feat = next(
vl.getFeatures(QgsFeatureRequest(QgsExpression('"verified" is true')))
)
other_feat = next(
vl.getFeatures(QgsFeatureRequest(QgsExpression('"verified" is false')))
)
self.assertEqual(qgis_feat["name"], "Xxx")
self.assertEqual(other_feat["name"], "qgis")

qgis_feat = next(vl.getFeatures(QgsFeatureRequest(QgsExpression('"verified"'))))
other_feat = next(
vl.getFeatures(QgsFeatureRequest(QgsExpression('not "verified"')))
)
self.assertEqual(qgis_feat["name"], "Xxx")
self.assertEqual(other_feat["name"], "qgis")

qgis_feat = next(
vl.getFeatures(QgsFeatureRequest(QgsExpression('"verified" = true')))
)
other_feat = next(
vl.getFeatures(QgsFeatureRequest(QgsExpression('"verified" = false')))
)
self.assertEqual(qgis_feat["name"], "Xxx")
self.assertEqual(other_feat["name"], "qgis")

form_scope = QgsExpressionContextUtils.formScope(qgis_feat)
form_exp = QgsExpression("current_value('name') = \"name\"")
ctx = QgsExpressionContext()
Expand Down

0 comments on commit c45551b

Please sign in to comment.