diff --git a/autotest/ogr/ogr_gpkg.py b/autotest/ogr/ogr_gpkg.py index a24249c32a27..0b0c4dadca8f 100755 --- a/autotest/ogr/ogr_gpkg.py +++ b/autotest/ogr/ogr_gpkg.py @@ -10664,3 +10664,31 @@ def test_gpkg_rename_hidden_table(tmp_vsimem): gdal.VSIFCloseL(f) assert "hidden_foo_table" not in content + + +############################################################################### +# Test creating duplicate field names + + +@gdaltest.enable_exceptions() +def test_gpkg_create_duplicate_field_names(tmp_vsimem): + + filename = str(tmp_vsimem / "test_gpkg_create_duplicate_field_names.gpkg") + with ogr.GetDriverByName("GPKG").CreateDataSource(filename) as ds: + lyr = ds.CreateLayer("test") + lyr.CreateField(ogr.FieldDefn("foo")) + with pytest.raises( + Exception, match="A field with the same name already exists" + ): + lyr.CreateField(ogr.FieldDefn("foo")) + assert lyr.GetLayerDefn().GetFieldCount() == 1 + with pytest.raises( + Exception, match="A field with the same name already exists" + ): + lyr.CreateField(ogr.FieldDefn("FOO")) + assert lyr.GetLayerDefn().GetFieldCount() == 1 + with pytest.raises( + Exception, match="It has the same name as the geometry field" + ): + lyr.CreateField(ogr.FieldDefn("geom")) + assert lyr.GetLayerDefn().GetFieldCount() == 1 diff --git a/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp b/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp index ced8b3ba1eb5..f970a0d53582 100644 --- a/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp +++ b/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp @@ -1729,6 +1729,24 @@ OGRErr OGRGeoPackageTableLayer::CreateField(const OGRFieldDefn *poField, GDALGeoPackageDataset::LaunderName(oFieldDefn.GetNameRef()) .c_str()); + if (m_poFeatureDefn->GetFieldIndex(oFieldDefn.GetNameRef()) >= 0) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot create field %s. " + "A field with the same name already exists.", + oFieldDefn.GetNameRef()); + return OGRERR_FAILURE; + } + + if (m_poFeatureDefn->GetGeomFieldIndex(oFieldDefn.GetNameRef()) >= 0) + { + CPLError(CE_Failure, CPLE_AppDefined, + "Cannot create field %s. " + "It has the same name as the geometry field.", + oFieldDefn.GetNameRef()); + return OGRERR_FAILURE; + } + if (m_pszFidColumn != nullptr && EQUAL(oFieldDefn.GetNameRef(), m_pszFidColumn) && poField->GetType() != OFTInteger &&