Skip to content

Commit f4bf1ec

Browse files
committedJun 1, 2018
[OGR provider] GPKG: allow repeated creation of int fields with len != 0 (fixes #19009)
1 parent bd65fc6 commit f4bf1ec

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed
 

‎src/providers/ogr/qgsogrprovider.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,10 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
15571557
returnvalue = false;
15581558
}
15591559
}
1560+
1561+
// Backup existing fields. We need them to 'restore' field type, length, precision
1562+
QgsFields oldFields = mAttributeFields;
1563+
15601564
loadFields();
15611565

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

1585+
// Restore field type, length, precision of existing fields as well
1586+
// We need that in scenarios where the user adds a int field with length != 0
1587+
// in a editing session, and repeat that again in another editing session
1588+
// Without the below hack, the length of the first added field would have
1589+
// been reset to zero, and QgsVectorLayerEditBuffer::commitChanges() would
1590+
// error out because of this.
1591+
// See https://issues.qgis.org/issues/19009
1592+
for ( auto field : oldFields )
1593+
{
1594+
int idx = mAttributeFields.lookupField( field.name() );
1595+
if ( idx >= 0 )
1596+
{
1597+
mAttributeFields[ idx ].setType( field.type() );
1598+
mAttributeFields[ idx ].setLength( field.length() );
1599+
mAttributeFields[ idx ].setPrecision( field.precision() );
1600+
}
1601+
}
1602+
15811603
return returnvalue;
15821604
}
15831605

‎tests/src/python/test_provider_ogr_gpkg.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,26 @@ def testRequestWithoutGeometryOnLayerMixedGeometry(self):
929929
features = [f for f in vl.getFeatures(request)]
930930
self.assertEqual(len(features), 1)
931931

932+
def testAddingTwoIntFieldsWithWidth(self):
933+
""" Test buggfix for https://issues.qgis.org/issues/19009 """
934+
935+
tmpfile = os.path.join(self.basetestpath, 'testRequestWithoutGeometryOnLayerMixedGeometry.gpkg')
936+
ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
937+
lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['SPATIAL_INDEX=NO'])
938+
lyr.CreateField(ogr.FieldDefn('a', ogr.OFTInteger))
939+
ds = None
940+
941+
vl = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr')
942+
self.assertTrue(vl.isValid())
943+
944+
vl.startEditing()
945+
self.assertTrue(vl.addAttribute(QgsField("b", QVariant.Int, "integer", 10)))
946+
self.assertTrue(vl.commitChanges())
947+
948+
vl.startEditing()
949+
self.assertTrue(vl.addAttribute(QgsField("c", QVariant.Int, "integer", 10)))
950+
self.assertTrue(vl.commitChanges())
951+
932952

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

0 commit comments

Comments
 (0)
Please sign in to comment.