Skip to content
Permalink
Browse files

[VirtualLayer] Catch exception while updating virtual layer stats

Fixes #34378
  • Loading branch information
troopa81 authored and nyalldawson committed Sep 25, 2020
1 parent 9de7be1 commit f6c42a7d81bc92aa00601312d7d3edeee3132ce7
Showing with 41 additions and 12 deletions.
  1. +21 −12 src/providers/virtual/qgsvirtuallayerprovider.cpp
  2. +20 −0 tests/src/python/test_provider_virtual.py
@@ -568,20 +568,30 @@ void QgsVirtualLayerProvider::updateStatistics() const
.arg( hasGeometry ? QStringLiteral( ",Min(MbrMinX(%1)),Min(MbrMinY(%1)),Max(MbrMaxX(%1)),Max(MbrMaxY(%1))" ).arg( quotedColumn( mDefinition.geometryField() ) ) : QString(),
mTableName,
subset );
Sqlite::Query q( mSqlite.get(), sql );
if ( q.step() == SQLITE_ROW )

try
{
mFeatureCount = q.columnInt64( 0 );
if ( hasGeometry )
Sqlite::Query q( mSqlite.get(), sql );
if ( q.step() == SQLITE_ROW )
{
double x1, y1, x2, y2;
x1 = q.columnDouble( 1 );
y1 = q.columnDouble( 2 );
x2 = q.columnDouble( 3 );
y2 = q.columnDouble( 4 );
mExtent = QgsRectangle( x1, y1, x2, y2 );
mFeatureCount = q.columnInt64( 0 );
if ( hasGeometry )
{
double x1, y1, x2, y2;
x1 = q.columnDouble( 1 );
y1 = q.columnDouble( 2 );
x2 = q.columnDouble( 3 );
y2 = q.columnDouble( 4 );
mExtent = QgsRectangle( x1, y1, x2, y2 );
}
mCachedStatistics = true;
}
mCachedStatistics = true;
}
catch ( std::runtime_error &e )
{
pushError( tr( "Error while executing feature count request : %1" ).arg( e.what() ) );
mFeatureCount = 0;
return;
}
}

@@ -709,4 +719,3 @@ QGISEXTERN QgsProviderGuiMetadata *providerGuiMetadataFactory()
return new QgsVirtualLayerProviderGuiMetadata();
}
#endif

@@ -1187,6 +1187,26 @@ def test_subset_string(self):
self.assertEqual(gpkg_virtual_layer.subsetString(), '"join_value" = \'twenty\'')
self.assertEqual(gpkg_virtual_layer.featureCount(), 1)

def test_feature_count_on_error(self):
"""Test that triggered exception while getting feature count on a badly defined
virtual layer is correctly caught (see https://github.com/qgis/QGIS/issues/34378)"""

l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france", "ogr",
QgsVectorLayer.LayerOptions(False))
self.assertEqual(l1.isValid(), True)
QgsProject.instance().addMapLayer(l1)

df = QgsVirtualLayerDefinition()
df.setQuery('select error')

vl = QgsVectorLayer(df.toString(), "testq", "virtual")
self.assertEqual(vl.isValid(), False)
self.assertEqual(vl.featureCount(), 0)
ids = [f.id() for f in vl.getFeatures()]
self.assertEqual(len(ids), 0)

QgsProject.instance().removeMapLayer(l1.id())


if __name__ == '__main__':
unittest.main()

0 comments on commit f6c42a7

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