Skip to content
Permalink
Browse files

Rollback rejection of features with too many attributes

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 0e68a3e77590ee4281b5728ed508f4aa7a1d1551
@@ -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 )
@@ -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())
@@ -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() )
{
@@ -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):

0 comments on commit 0e68a3e

Please sign in to comment.
You can’t perform that action at this time.