From 87b7dad7dc199b714e46723581060d52259e408b Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Wed, 18 Oct 2023 15:12:52 +0200 Subject: [PATCH] Fix extent computation in QgsVirtualLayerProvider Extent should be set to null if there are no rows or geometric field or computed min/max envelope ordinates are null. Also makes the implementation more readable (hopefully). --- .../virtual/qgsvirtuallayerprovider.cpp | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/providers/virtual/qgsvirtuallayerprovider.cpp b/src/providers/virtual/qgsvirtuallayerprovider.cpp index 10289dbe48523..16cfab46c7944 100644 --- a/src/providers/virtual/qgsvirtuallayerprovider.cpp +++ b/src/providers/virtual/qgsvirtuallayerprovider.cpp @@ -41,11 +41,6 @@ const QString QgsVirtualLayerProvider::VIRTUAL_LAYER_KEY = QStringLiteral( "virt const QString QgsVirtualLayerProvider::VIRTUAL_LAYER_DESCRIPTION = QStringLiteral( "Virtual layer data provider" ); const QString QgsVirtualLayerProvider::VIRTUAL_LAYER_QUERY_VIEW = QStringLiteral( "_query" ); -static QString quotedColumn( QString name ) -{ - return "\"" + name.replace( QLatin1String( "\"" ), QLatin1String( "\"\"" ) ) + "\""; -} - #define PROVIDER_ERROR( msg ) do { mError = QgsError( msg, QgsVirtualLayerProvider::VIRTUAL_LAYER_KEY ); QgsDebugError( msg ); } while(0) @@ -560,11 +555,24 @@ QgsRectangle QgsVirtualLayerProvider::extent() const void QgsVirtualLayerProvider::updateStatistics() const { const bool hasGeometry = mDefinition.geometryWkbType() != Qgis::WkbType::NoGeometry; - const QString subset = mSubset.isEmpty() ? QString() : " WHERE " + mSubset; - const QString sql = QStringLiteral( "SELECT Count(*)%1 FROM %2%3" ) - .arg( hasGeometry ? QStringLiteral( ",Min(MbrMinX(%1)),Min(MbrMinY(%1)),Max(MbrMaxX(%1)),Max(MbrMaxY(%1))" ).arg( quotedColumn( mDefinition.geometryField() ) ) : QString(), - mTableName, - subset ); + + QString sql = QStringLiteral( "SELECT Count(1)" ); + + if ( hasGeometry ) + { + sql += QStringLiteral( + ", Min(MbrMinX(%1)), Min(MbrMinY(%1)), Max(MbrMaxX(%1)), Max(MbrMaxY(%1))" + ).arg( QgsSqliteUtils::quotedIdentifier( mDefinition.geometryField() ) ); + } + + sql += QStringLiteral( " FROM %1" ) .arg( mTableName ); + + if ( !mSubset.isEmpty() ) + { + sql += " WHERE ( " + mSubset + ')'; + } + + mExtent.setMinimal(); // setNull(), basically try { @@ -572,7 +580,7 @@ void QgsVirtualLayerProvider::updateStatistics() const if ( q.step() == SQLITE_ROW ) { mFeatureCount = q.columnInt64( 0 ); - if ( hasGeometry ) + if ( mFeatureCount && hasGeometry ) { double x1, y1, x2, y2; x1 = q.columnDouble( 1 );