Skip to content

Commit

Permalink
[OGR provider] GPKG: allow repeated creation of int fields with len !…
Browse files Browse the repository at this point in the history
…= 0 (fixes #19009)
  • Loading branch information
rouault committed Jun 1, 2018
1 parent bd65fc6 commit f4bf1ec
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -1557,6 +1557,10 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
returnvalue = false;
}
}

// Backup existing fields. We need them to 'restore' field type, length, precision
QgsFields oldFields = mAttributeFields;

loadFields();

// The check in QgsVectorLayerEditBuffer::commitChanges() is questionable with
Expand All @@ -1578,6 +1582,24 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
}
}

// Restore field type, length, precision of existing fields as well
// We need that in scenarios where the user adds a int field with length != 0
// in a editing session, and repeat that again in another editing session
// Without the below hack, the length of the first added field would have
// been reset to zero, and QgsVectorLayerEditBuffer::commitChanges() would
// error out because of this.
// See https://issues.qgis.org/issues/19009
for ( auto field : oldFields )
{
int idx = mAttributeFields.lookupField( field.name() );
if ( idx >= 0 )
{
mAttributeFields[ idx ].setType( field.type() );
mAttributeFields[ idx ].setLength( field.length() );
mAttributeFields[ idx ].setPrecision( field.precision() );
}
}

return returnvalue;
}

Expand Down
20 changes: 20 additions & 0 deletions tests/src/python/test_provider_ogr_gpkg.py
Expand Up @@ -929,6 +929,26 @@ def testRequestWithoutGeometryOnLayerMixedGeometry(self):
features = [f for f in vl.getFeatures(request)]
self.assertEqual(len(features), 1)

def testAddingTwoIntFieldsWithWidth(self):
""" Test buggfix for https://issues.qgis.org/issues/19009 """

tmpfile = os.path.join(self.basetestpath, 'testRequestWithoutGeometryOnLayerMixedGeometry.gpkg')
ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['SPATIAL_INDEX=NO'])
lyr.CreateField(ogr.FieldDefn('a', ogr.OFTInteger))
ds = None

vl = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr')
self.assertTrue(vl.isValid())

vl.startEditing()
self.assertTrue(vl.addAttribute(QgsField("b", QVariant.Int, "integer", 10)))
self.assertTrue(vl.commitChanges())

vl.startEditing()
self.assertTrue(vl.addAttribute(QgsField("c", QVariant.Int, "integer", 10)))
self.assertTrue(vl.commitChanges())


if __name__ == '__main__':
unittest.main()

0 comments on commit f4bf1ec

Please sign in to comment.