Skip to content

Commit

Permalink
[Backport release-3_40] Fix boolean filtering in QGIS expressions wit…
Browse files Browse the repository at this point in the history
…h WFS layers (#60076)

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
qgis-bot authored Jan 8, 2025
1 parent a5375d4 commit 33fc10e
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 33fc10e

Please sign in to comment.