Skip to content

Commit

Permalink
Rollback rejection of features with too many attributes
Browse files Browse the repository at this point in the history
Turns out editable joins rely on this situation. Instead change
the providers to warn on this occurance, and make the memory
provider alone truncate the extra attributes (since it doesn't
have an external backend or disk based format which natively
applies this truncation)
  • Loading branch information
nyalldawson committed Feb 17, 2018
1 parent 5ee54e0 commit 0e68a3e
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 15 deletions.
5 changes: 3 additions & 2 deletions src/core/providers/memory/qgsmemoryprovider.cpp
Expand Up @@ -369,8 +369,9 @@ bool QgsMemoryProvider::addFeatures( QgsFeatureList &flist, Flags )
{
// too many attributes
pushError( tr( "Feature has too many attributes (expecting %1, received %2)" ).arg( fieldCount ).arg( it->attributes().count() ) );
result = false;
continue;
QgsAttributes attributes = it->attributes();
attributes.resize( mFields.count() );
it->setAttributes( attributes );
}

if ( it->hasGeometry() && mWkbType == QgsWkbTypes::NoGeometry )
Expand Down
2 changes: 1 addition & 1 deletion src/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -1330,7 +1330,7 @@ bool QgsOgrProvider::addFeaturePrivate( QgsFeature &f, Flags flags )
if ( ogrAttId >= fdef.GetFieldCount() )
{
pushError( tr( "Feature has too many attributes (expecting %1, received %2)" ).arg( fdef.GetFieldCount() ).arg( f.attributes().count() ) );
return false;
continue;
}

//if(!s.isEmpty())
Expand Down
7 changes: 0 additions & 7 deletions src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -2148,13 +2148,6 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist, Flags flags )
{
QgsAttributes attrs = features->attributes();

if ( attrs.count() > mAttributeFields.count() )
{
pushError( tr( "Feature has too many attributes (expecting %1, received %2)" ).arg( mAttributeFields.count() ).arg( attrs.count() ) );
returnvalue = false;
continue;
}

QStringList params;
if ( !mGeometryColumn.isNull() )
{
Expand Down
11 changes: 6 additions & 5 deletions tests/src/python/providertestbase.py
Expand Up @@ -477,19 +477,20 @@ def testAddFeatureExtraAttributes(self):
if not l.dataProvider().capabilities() & QgsVectorDataProvider.AddFeatures:
return

# test that adding features with too many attributes rejects the feature
# test that adding features with too many attributes drops these attributes
# we be more tricky and also add a valid feature to stress test the provider
f1 = QgsFeature()
f1.setAttributes([6, -220, NULL, 'String', '15'])
f2 = QgsFeature()
f2.setAttributes([7, -230, NULL, 'String', '15', 15, 16, 17])

result, added = l.dataProvider().addFeatures([f1, f2])
self.assertFalse(result, 'Provider returned True to addFeatures with extra attributes. Providers should reject these features.')
self.assertTrue(result,
'Provider returned False to addFeatures with extra attributes. Providers should accept these features but truncate the extra attributes.')

# make sure feature was not added
added = [f for f in l.dataProvider().getFeatures() if f['pk'] == 7]
self.assertFalse(added)
# make sure feature was added correctyl
added = [f for f in l.dataProvider().getFeatures() if f['pk'] == 7][0]
self.assertEqual(added.attributes(), [7, -230, NULL, 'String', '15'])

def testAddFeatureWrongGeomType(self):
if not getattr(self, 'getEditableLayer', None):
Expand Down

0 comments on commit 0e68a3e

Please sign in to comment.