Skip to content
Permalink
Browse files

[OGR provider] GPKG: allow repeated creation of int fields with len !…

…= 0 (fixes #19009)
  • Loading branch information
rouault committed Jun 1, 2018
1 parent bd65fc6 commit f4bf1ec90709829642b9af858df7500cba3ade31
Showing with 42 additions and 0 deletions.
  1. +22 −0 src/providers/ogr/qgsogrprovider.cpp
  2. +20 −0 tests/src/python/test_provider_ogr_gpkg.py
@@ -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
@@ -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;
}

@@ -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.
You can’t perform that action at this time.