diff --git a/autotest/ogr/ogr_pg.py b/autotest/ogr/ogr_pg.py index b517527222d2..4efceeff0d1e 100755 --- a/autotest/ogr/ogr_pg.py +++ b/autotest/ogr/ogr_pg.py @@ -6231,3 +6231,41 @@ def test_ogr_pg_empty_search_path(pg_ds): finally: ds.ExecuteSQL(f"ALTER ROLE {current_user} SET search_path = {old_search_path}") + + +############################################################################### +# Test appending to a layer where a field name was truncated to 63 characters. + + +@only_without_postgis +@gdaltest.enable_exceptions() +def test_ogr_pg_findfield(pg_ds): + + src_ds = ogr.GetDriverByName("Memory").CreateDataSource("") + src_lyr = src_ds.CreateLayer("test_very_long_field_name") + src_lyr.CreateField( + ogr.FieldDefn( + "veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeryyyyyyyyyyyyyyyyyyyyyyloooooooooooooong" + ) + ) + f = ogr.Feature(src_lyr.GetLayerDefn()) + f.SetField(0, "foo") + src_lyr.CreateFeature(f) + + with gdal.quiet_errors(): + gdal.VectorTranslate(pg_ds.GetDescription(), src_ds) + + with gdal.quiet_errors(): + gdal.VectorTranslate(pg_ds.GetDescription(), src_ds, accessMode="append") + + lyr = pg_ds.GetLayerByName("test_very_long_field_name") + assert [f.GetField(0) for f in lyr] == ["foo", None] + + with gdal.quiet_errors(): + gdal.VectorTranslate( + pg_ds.GetDescription(), + src_ds, + accessMode="append", + relaxedFieldNameMatch=True, + ) + assert [f.GetField(0) for f in lyr] == ["foo", None, "foo"] diff --git a/ogr/ogrsf_frmts/pg/ogr_pg.h b/ogr/ogrsf_frmts/pg/ogr_pg.h index 396d34c58956..9981131a086c 100644 --- a/ogr/ogrsf_frmts/pg/ogr_pg.h +++ b/ogr/ogrsf_frmts/pg/ogr_pg.h @@ -445,6 +445,8 @@ class OGRPGTableLayer final : public OGRPGLayer GDALProgressFunc pfnProgress, void *pProgressData) override; + int FindFieldIndex(const char *pszFieldName, int bExactMatch) override; + // follow methods are not base class overrides void SetLaunderFlag(int bFlag) { diff --git a/ogr/ogrsf_frmts/pg/ogrpgtablelayer.cpp b/ogr/ogrsf_frmts/pg/ogrpgtablelayer.cpp index f92757e155fd..44f480c6d47d 100644 --- a/ogr/ogrsf_frmts/pg/ogrpgtablelayer.cpp +++ b/ogr/ogrsf_frmts/pg/ogrpgtablelayer.cpp @@ -4034,4 +4034,25 @@ OGRGeometryTypeCounter *OGRPGTableLayer::GetGeometryTypes( return pasRet; } +/************************************************************************/ +/* FindFieldIndex() */ +/************************************************************************/ + +int OGRPGTableLayer::FindFieldIndex(const char *pszFieldName, int bExactMatch) +{ + const auto poLayerDefn = GetLayerDefn(); + int iField = poLayerDefn->GetFieldIndex(pszFieldName); + + if (!bExactMatch && iField < 0 && bLaunderColumnNames) + { + CPLErrorStateBackuper oErrorStateBackuper(CPLQuietErrorHandler); + char *pszSafeName = + OGRPGCommonLaunderName(pszFieldName, "PG", m_bUTF8ToASCII); + iField = poLayerDefn->GetFieldIndex(pszSafeName); + CPLFree(pszSafeName); + } + + return iField; +} + #undef PQexec