Skip to content

Commit a2756b9

Browse files
committed
Ensure that providers fetch geometry for a QgsFeatureRequest
with an expression filter which requires geometry (cherry-picked from 858914e)
1 parent e3556f7 commit a2756b9

9 files changed

+28
-4
lines changed

src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ QgsDelimitedTextFeatureIterator::QgsDelimitedTextFeatureIterator( QgsDelimitedTe
128128
!( mRequest.flags() & QgsFeatureRequest::NoGeometry )
129129
|| mTestGeometry
130130
|| ( mTestSubset && mSource->mSubsetExpression->needsGeometry() )
131+
|| ( request.filterType() == QgsFeatureRequest::FilterExpression && request.filterExpression()->needsGeometry() )
131132
)
132133
)
133134
{

src/providers/mssql/qgsmssqlfeatureiterator.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ void QgsMssqlFeatureIterator::BuildStatement( const QgsFeatureRequest& request )
102102
}
103103

104104
// get geometry col
105-
if ( !( request.flags() & QgsFeatureRequest::NoGeometry ) && mSource->isSpatial() )
105+
if (( !( request.flags() & QgsFeatureRequest::NoGeometry )
106+
|| ( request.filterType() == QgsFeatureRequest::FilterExpression && request.filterExpression()->needsGeometry() )
107+
)
108+
&& mSource->isSpatial() )
106109
{
107110
mStatement += QString( ",[%1]" ).arg( mSource->mGeometryColName );
108111
}

src/providers/ogr/qgsogrfeatureiterator.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool
7474
}
7575
mRequest.setSubsetOfAttributes( attrs );
7676
}
77+
if ( request.filterType() == QgsFeatureRequest::FilterExpression && request.filterExpression()->needsGeometry() )
78+
{
79+
mFetchGeometry = true;
80+
}
7781

7882
// make sure we fetch just relevant fields
7983
// unless it's a VRT data source filtered by geometry as we don't know which

src/providers/oracle/qgsoraclefeatureiterator.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ QgsOracleFeatureIterator::QgsOracleFeatureIterator( QgsOracleFeatureSource* sour
6868
{
6969
// fetch geometry if requested
7070
mFetchGeometry = ( mRequest.flags() & QgsFeatureRequest::NoGeometry ) == 0;
71+
if ( mRequest.filterType() == QgsFeatureRequest::FilterExpression && mRequest.filterExpression()->needsGeometry() )
72+
{
73+
mFetchGeometry = true;
74+
}
7175

7276
if ( !mRequest.filterRect().isNull() )
7377
{

src/providers/postgres/qgspostgresfeatureiterator.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresFeatureSource
3737
, mExpressionCompiled( false )
3838
, mOrderByCompiled( false )
3939
, mLastFetch( false )
40+
, mFilterRequiresGeometry( false )
4041
{
4142
if ( !source->mTransactionConnection )
4243
{
@@ -101,6 +102,7 @@ QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresFeatureSource
101102
}
102103
mRequest.setSubsetOfAttributes( attrs );
103104
}
105+
mFilterRequiresGeometry = request.filterExpression()->needsGeometry();
104106

105107
if ( QSettings().value( "/qgis/compileExpressions", true ).toBool() )
106108
{
@@ -436,7 +438,7 @@ QString QgsPostgresFeatureIterator::whereClauseRect()
436438

437439
bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause, long limit, bool closeOnFail, const QString& orderBy )
438440
{
439-
mFetchGeometry = !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && !mSource->mGeometryColumn.isNull();
441+
mFetchGeometry = ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) || mFilterRequiresGeometry ) && !mSource->mGeometryColumn.isNull();
440442
#if 0
441443
// TODO: check that all field indexes exist
442444
if ( !hasAllFields )

src/providers/postgres/qgspostgresfeatureiterator.h

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class QgsPostgresFeatureIterator : public QgsAbstractFeatureIteratorFromSource<Q
129129
bool mExpressionCompiled;
130130
bool mOrderByCompiled;
131131
bool mLastFetch;
132+
bool mFilterRequiresGeometry;
132133
};
133134

134135
#endif // QGSPOSTGRESFEATUREITERATOR_H

src/providers/spatialite/qgsspatialitefeatureiterator.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ QgsSpatiaLiteFeatureIterator::QgsSpatiaLiteFeatureIterator( QgsSpatiaLiteFeature
9595
}
9696
mRequest.setSubsetOfAttributes( attrs );
9797
}
98+
if ( request.filterExpression()->needsGeometry() )
99+
{
100+
mFetchGeometry = true;
101+
}
98102

99103
if ( QSettings().value( "/qgis/compileExpressions", true ).toBool() )
100104
{

src/providers/virtual/qgsvirtuallayerfeatureiterator.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ QgsVirtualLayerFeatureIterator::QgsVirtualLayerFeatureIterator( QgsVirtualLayerF
121121
}
122122
}
123123
// the last column is the geometry, if any
124-
if ( !( request.flags() & QgsFeatureRequest::NoGeometry ) && !mDefinition.geometryField().isNull() && mDefinition.geometryField() != "*no*" )
124+
if (( !( request.flags() & QgsFeatureRequest::NoGeometry )
125+
|| ( request.filterType() == QgsFeatureRequest::FilterExpression && request.filterExpression()->needsGeometry() ) )
126+
&& !mDefinition.geometryField().isNull() && mDefinition.geometryField() != "*no*" )
125127
{
126128
columns += "," + quotedColumn( mDefinition.geometryField() );
127129
}

tests/src/python/providertestbase.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def testGetFeatures(self):
6262
self.assertFalse(geometries[pk], 'Expected null geometry for {}'.format(pk))
6363

6464
def assert_query(self, provider, expression, expected):
65-
result = set([f['pk'] for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression(expression))])
65+
result = set([f['pk'] for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression(expression).setFlags(QgsFeatureRequest.NoGeometry))])
6666
assert set(expected) == result, 'Expected {} and got {} when testing expression "{}"'.format(set(expected), result, expression)
6767

6868
# Also check that filter works when referenced fields are not being retrieved by request
@@ -154,6 +154,9 @@ def runGetFeatureTests(self, provider):
154154
# against numeric literals
155155
self.assert_query(provider, 'num_char IN (2, 4, 5)', [2, 4, 5])
156156

157+
# geometry
158+
self.assert_query(provider, 'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))', [1, 2])
159+
157160
def testGetFeaturesUncompiled(self):
158161
try:
159162
self.disableCompiler()

0 commit comments

Comments
 (0)