Skip to content

Commit ba416d2

Browse files
authored
Merge pull request #9527 from manisandro/master
Misc crash fixes
2 parents ab340f2 + 0360b45 commit ba416d2

12 files changed

+70
-25
lines changed

python/core/auto_generated/qgsfeaturerequest.sip.in

+11
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,17 @@ Deserialize from XML
243243
QSet<QString> usedAttributes() const;
244244
%Docstring
245245
Returns a set of used attributes
246+
247+
.. note::
248+
249+
The returned attributes names are NOT guaranteed to be valid.
250+
%End
251+
252+
QSet<int> usedAttributeIndices( const QgsFields &fields ) const;
253+
%Docstring
254+
Returns a set of used, validated attribute indices
255+
256+
.. versionadded:: 3.8
246257
%End
247258

248259
QString dump() const;

src/core/qgsfeaturerequest.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,24 @@ QSet<QString> QgsFeatureRequest::OrderBy::usedAttributes() const
485485
return usedAttributes;
486486
}
487487

488+
QSet<int> QgsFeatureRequest::OrderBy::usedAttributeIndices( const QgsFields &fields ) const
489+
{
490+
QSet<int> usedAttributeIdx;
491+
for ( const OrderByClause &clause : *this )
492+
{
493+
const auto referencedColumns = clause.expression().referencedColumns();
494+
for ( const QString &fieldName : referencedColumns )
495+
{
496+
int idx = fields.lookupField( fieldName );
497+
if ( idx >= 0 )
498+
{
499+
usedAttributeIdx.insert( idx );
500+
}
501+
}
502+
}
503+
return usedAttributeIdx;
504+
}
505+
488506
QString QgsFeatureRequest::OrderBy::dump() const
489507
{
490508
QStringList results;

src/core/qgsfeaturerequest.h

+7
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,16 @@ class CORE_EXPORT QgsFeatureRequest
257257

258258
/**
259259
* Returns a set of used attributes
260+
* \note The returned attributes names are NOT guaranteed to be valid.
260261
*/
261262
QSet<QString> CORE_EXPORT usedAttributes() const;
262263

264+
/**
265+
* Returns a set of used, validated attribute indices
266+
* \since QGIS 3.8
267+
*/
268+
QSet<int> CORE_EXPORT usedAttributeIndices( const QgsFields &fields ) const;
269+
263270
/**
264271
* Dumps the content to an SQL equivalent syntax
265272
*/

src/core/qgsvectorlayer.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1594,6 +1594,7 @@ bool QgsVectorLayer::setDataProvider( QString const &provider, const QgsDataProv
15941594
if ( !mValid )
15951595
{
15961596
QgsDebugMsgLevel( QStringLiteral( "Invalid provider plugin %1" ).arg( QString( mDataSource.toUtf8() ) ), 2 );
1597+
return false;
15971598
}
15981599

15991600
if ( mDataProvider->capabilities() & QgsVectorDataProvider::ReadLayerMetadata )

src/core/qgsvectorlayerfeatureiterator.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,10 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
189189
// and only modify the subset if we cannot.
190190
if ( !mProviderRequest.orderBy().isEmpty() )
191191
{
192-
Q_FOREACH ( const QString &attr, mProviderRequest.orderBy().usedAttributes() )
192+
const auto usedAttributeIndices = mProviderRequest.orderBy().usedAttributeIndices( mSource->mFields );
193+
for ( int attrIndex : usedAttributeIndices )
193194
{
194-
providerSubset << mSource->mFields.lookupField( attr );
195+
providerSubset << attrIndex;
195196
}
196197
}
197198

src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,9 @@ QgsDelimitedTextFeatureIterator::QgsDelimitedTextFeatureIterator( QgsDelimitedTe
161161
if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes && !mRequest.orderBy().isEmpty() )
162162
{
163163
QgsAttributeList attrs = request.subsetOfAttributes();
164-
Q_FOREACH ( const QString &attr, mRequest.orderBy().usedAttributes() )
164+
const auto usedAttributeIndices = mRequest.orderBy().usedAttributeIndices( mSource->mFields );
165+
for ( int attrIndex : usedAttributeIndices )
165166
{
166-
int attrIndex = mSource->mFields.lookupField( attr );
167167
if ( !attrs.contains( attrIndex ) )
168168
attrs << attrIndex;
169169
}

src/providers/mssql/qgsmssqlfeatureiterator.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,9 @@ void QgsMssqlFeatureIterator::BuildStatement( const QgsFeatureRequest &request )
9595
}
9696

9797
// ensure that all attributes required for order by are fetched
98-
const QSet< QString > orderByAttributes = mRequest.orderBy().usedAttributes();
99-
for ( const QString &attr : orderByAttributes )
98+
const auto usedAttributeIndices = mRequest.orderBy().usedAttributeIndices( mSource->mFields );
99+
for ( int attrIndex : usedAttributeIndices )
100100
{
101-
int attrIndex = mSource->mFields.lookupField( attr );
102101
if ( !attrs.contains( attrIndex ) )
103102
attrs << attrIndex;
104103
}

src/providers/ogr/qgsogrfeatureiterator.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,10 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource *source, bool
136136
if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes && !mRequest.orderBy().isEmpty() )
137137
{
138138
QSet<int> attributeIndexes;
139-
Q_FOREACH ( const QString &attr, mRequest.orderBy().usedAttributes() )
139+
const auto usedAttributeIndices = mRequest.orderBy().usedAttributeIndices( mSource->mFields );
140+
for ( int attrIdx : usedAttributeIndices )
140141
{
141-
attributeIndexes << mSource->mFields.lookupField( attr );
142+
attributeIndexes << attrIdx;
142143
}
143144
attributeIndexes += attrs.toSet();
144145
attrs = attributeIndexes.toList();

src/providers/postgres/qgspostgresfeatureiterator.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,9 @@ QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresFeatureSource
186186
if ( !mOrderByCompiled && mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
187187
{
188188
QgsAttributeList attrs = mRequest.subsetOfAttributes();
189-
Q_FOREACH ( const QString &attr, mRequest.orderBy().usedAttributes() )
189+
const auto usedAttributeIndices = mRequest.orderBy().usedAttributeIndices( mSource->mFields );
190+
for ( int attrIndex : usedAttributeIndices )
190191
{
191-
int attrIndex = mSource->mFields.lookupField( attr );
192192
if ( !attrs.contains( attrIndex ) )
193193
attrs << attrIndex;
194194
}

src/providers/spatialite/qgsspatialitefeatureiterator.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,10 @@ QgsSpatiaLiteFeatureIterator::QgsSpatiaLiteFeatureIterator( QgsSpatiaLiteFeature
196196
if ( !mOrderByCompiled && mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes && !mRequest.orderBy().isEmpty() )
197197
{
198198
QSet<int> attributeIndexes;
199-
Q_FOREACH ( const QString &attr, mRequest.orderBy().usedAttributes() )
199+
const auto usedAttributeIndices = mRequest.orderBy().usedAttributeIndices( mSource->mFields );
200+
for ( int attrIdx : usedAttributeIndices )
200201
{
201-
attributeIndexes << mSource->mFields.lookupField( attr );
202+
attributeIndexes << attrIdx;
202203
}
203204
attributeIndexes += mRequest.subsetOfAttributes().toSet();
204205
mRequest.setSubsetOfAttributes( attributeIndexes.toList() );

src/providers/virtual/qgsvirtuallayerfeatureiterator.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ QgsVirtualLayerFeatureIterator::QgsVirtualLayerFeatureIterator( QgsVirtualLayerF
128128
if ( request.flags() & QgsFeatureRequest::SubsetOfAttributes )
129129
{
130130
// copy only selected fields
131-
Q_FOREACH ( int idx, request.subsetOfAttributes() )
131+
const auto subsetOfAttributes = request.subsetOfAttributes();
132+
for ( int idx : subsetOfAttributes )
132133
{
133134
mAttributes << idx;
134135
}
@@ -147,9 +148,9 @@ QgsVirtualLayerFeatureIterator::QgsVirtualLayerFeatureIterator( QgsVirtualLayerF
147148
// also need attributes required by order by
148149
if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes && !mRequest.orderBy().isEmpty() )
149150
{
150-
Q_FOREACH ( const QString &attr, mRequest.orderBy().usedAttributes() )
151+
const auto usedAttributeIndices = mRequest.orderBy().usedAttributeIndices( mSource->mFields );
152+
for ( int attrIdx : usedAttributeIndices )
151153
{
152-
int attrIdx = mSource->mFields.lookupField( attr );
153154
if ( !mAttributes.contains( attrIdx ) )
154155
mAttributes << attrIdx;
155156
}

src/providers/wfs/qgswfsfeatureiterator.cpp

+14-9
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,8 @@ QgsFeatureRequest QgsWFSFeatureIterator::buildRequestCache( int genCounter )
10301030
{
10311031
QgsFields dataProviderFields = mShared->mCacheDataProvider->fields();
10321032
QgsAttributeList cacheSubSet;
1033-
Q_FOREACH ( int i, mRequest.subsetOfAttributes() )
1033+
const auto subsetOfAttributes = mRequest.subsetOfAttributes();
1034+
for ( int i : subsetOfAttributes )
10341035
{
10351036
int idx = dataProviderFields.indexFromName( mShared->mFields.at( i ).name() );
10361037
if ( idx >= 0 )
@@ -1043,7 +1044,8 @@ QgsFeatureRequest QgsWFSFeatureIterator::buildRequestCache( int genCounter )
10431044
// ensure that all attributes required for expression filter are being fetched
10441045
if ( mRequest.filterType() == QgsFeatureRequest::FilterExpression )
10451046
{
1046-
Q_FOREACH ( const QString &field, mRequest.filterExpression()->referencedColumns() )
1047+
const auto referencedColumns = mRequest.filterExpression()->referencedColumns();
1048+
for ( const QString &field : referencedColumns )
10471049
{
10481050
int idx = dataProviderFields.indexFromName( field );
10491051
if ( idx >= 0 && !cacheSubSet.contains( idx ) )
@@ -1057,15 +1059,18 @@ QgsFeatureRequest QgsWFSFeatureIterator::buildRequestCache( int genCounter )
10571059
// also need attributes required by order by
10581060
if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes && !mRequest.orderBy().isEmpty() )
10591061
{
1060-
Q_FOREACH ( const QString &attr, mRequest.orderBy().usedAttributes() )
1062+
const auto usedProviderAttributeIndices = mRequest.orderBy().usedAttributeIndices( dataProviderFields );
1063+
for ( int attrIdx : usedProviderAttributeIndices )
10611064
{
1062-
int idx = dataProviderFields.indexFromName( attr );
1063-
if ( idx >= 0 && !cacheSubSet.contains( idx ) )
1064-
cacheSubSet.append( idx );
1065+
if ( !cacheSubSet.contains( attrIdx ) )
1066+
cacheSubSet.append( attrIdx );
1067+
}
10651068

1066-
idx = mShared->mFields.indexFromName( attr );
1067-
if ( idx >= 0 && !mSubSetAttributes.contains( idx ) )
1068-
mSubSetAttributes.append( idx );
1069+
const auto usedSharedAttributeIndices = mRequest.orderBy().usedAttributeIndices( mShared->mFields );
1070+
for ( int attrIdx : usedSharedAttributeIndices )
1071+
{
1072+
if ( !mSubSetAttributes.contains( attrIdx ) )
1073+
mSubSetAttributes.append( attrIdx );
10691074
}
10701075
}
10711076

0 commit comments

Comments
 (0)