Skip to content

Commit

Permalink
Fix extent computation in QgsVirtualLayerProvider
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
strk committed Oct 18, 2023
1 parent 2d953c2 commit 87b7dad
Showing 1 changed file with 19 additions and 11 deletions.
30 changes: 19 additions & 11 deletions src/providers/virtual/qgsvirtuallayerprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down Expand Up @@ -560,19 +555,32 @@ 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
{
Sqlite::Query q( mSqlite.get(), sql );
if ( q.step() == SQLITE_ROW )
{
mFeatureCount = q.columnInt64( 0 );
if ( hasGeometry )
if ( mFeatureCount && hasGeometry )
{
double x1, y1, x2, y2;
x1 = q.columnDouble( 1 );
Expand Down

0 comments on commit 87b7dad

Please sign in to comment.