Skip to content
Permalink
Browse files

[VirtualLayer] Catch exception while updating virtual layer stats

Fixes #34378
  • Loading branch information
troopa81 committed Sep 24, 2020
1 parent f48eb31 commit f3a5b69691a6d2f88b5701f6df0bbb43f3d09f7c
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
@@ -570,20 +570,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;
}
}

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

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

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())

def test_bool_fields(self):

ml = QgsVectorLayer("NoGeometry?field=a:int&field=b:boolean", "mem", "memory")

0 comments on commit f3a5b69

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