[VirtualLayer] Catch exception while updating virtual layer stats

Fixes #34378
This commit is contained in:
Julien Cabieces 2020-09-25 00:37:33 +02:00 committed by GitHub
parent f48eb3109a
commit f3a5b69691
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 12 deletions

View File

@ -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

View File

@ -1271,6 +1271,26 @@ class TestQgsVirtualLayerProvider(unittest.TestCase, ProviderTestCase):
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")