Skip to content

Commit 44cd638

Browse files
authored
Merge pull request #9950 from qgis/backport-9939-to-release-3_6
[Backport release-3_6] Fix opening of GeoPackage datasets with foreign key violation
2 parents da9b8f8 + e6d220d commit 44cd638

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

src/providers/gdal/qgsgdalproviderbase.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,16 @@ QgsRectangle QgsGdalProviderBase::extent( GDALDatasetH gdalDataset )const
261261

262262
GDALDatasetH QgsGdalProviderBase::gdalOpen( const char *pszFilename, GDALAccess eAccess )
263263
{
264+
bool modify_OGR_GPKG_FOREIGN_KEY_CHECK = !CPLGetConfigOption( "OGR_GPKG_FOREIGN_KEY_CHECK", nullptr );
265+
if ( modify_OGR_GPKG_FOREIGN_KEY_CHECK )
266+
{
267+
CPLSetThreadLocalConfigOption( "OGR_GPKG_FOREIGN_KEY_CHECK", "NO" );
268+
}
264269
GDALDatasetH hDS = GDALOpen( pszFilename, eAccess );
270+
if ( modify_OGR_GPKG_FOREIGN_KEY_CHECK )
271+
{
272+
CPLSetThreadLocalConfigOption( "OGR_GPKG_FOREIGN_KEY_CHECK", nullptr );
273+
}
265274
return hDS;
266275
}
267276

src/providers/ogr/qgsogrprovider.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -3845,11 +3845,21 @@ GDALDatasetH QgsOgrProviderUtils::GDALOpenWrapper( const char *pszPath, bool bUp
38453845
bIsLocalGpkg = true;
38463846
}
38473847

3848+
bool modify_OGR_GPKG_FOREIGN_KEY_CHECK = !CPLGetConfigOption( "OGR_GPKG_FOREIGN_KEY_CHECK", nullptr );
3849+
if ( modify_OGR_GPKG_FOREIGN_KEY_CHECK )
3850+
{
3851+
CPLSetThreadLocalConfigOption( "OGR_GPKG_FOREIGN_KEY_CHECK", "NO" );
3852+
}
3853+
38483854
const int nOpenFlags = GDAL_OF_VECTOR | ( bUpdate ? GDAL_OF_UPDATE : 0 );
38493855
GDALDatasetH hDS = GDALOpenEx( pszPath, nOpenFlags, nullptr, papszOpenOptions, nullptr );
38503856
CSLDestroy( papszOpenOptions );
38513857

38523858
CPLSetThreadLocalConfigOption( "OGR_SQLITE_JOURNAL", nullptr );
3859+
if ( modify_OGR_GPKG_FOREIGN_KEY_CHECK )
3860+
{
3861+
CPLSetThreadLocalConfigOption( "OGR_GPKG_FOREIGN_KEY_CHECK", nullptr );
3862+
}
38533863

38543864
if ( !hDS )
38553865
{

tests/src/python/test_provider_ogr_gpkg.py

+19
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,25 @@ def testUniqueValuesOnFidColumn(self):
13441344
self.assertEqual(vl1.uniqueValues(0), {1, 2})
13451345
self.assertEqual(vl1.uniqueValues(1), {'one', 'two'})
13461346

1347+
def testForeignKeyViolation(self):
1348+
"""Test that we can open a dataset with a foreign key violation"""
1349+
1350+
tmpfile = os.path.join(self.basetestpath, 'testForeignKeyViolation.gpkg')
1351+
ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
1352+
lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint)
1353+
f = ogr.Feature(lyr.GetLayerDefn())
1354+
f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 1)'))
1355+
lyr.CreateFeature(f)
1356+
ds.ExecuteSQL("PRAGMA foreign_keys = OFF")
1357+
ds.ExecuteSQL("CREATE TABLE foo(id INTEGER)")
1358+
ds.ExecuteSQL("CREATE TABLE bar(fkey INTEGER, CONSTRAINT fkey_constraint FOREIGN KEY (fkey) REFERENCES foo(id))")
1359+
ds.ExecuteSQL("INSERT INTO bar VALUES (1)")
1360+
ds = None
1361+
vl = QgsVectorLayer('{}'.format(tmpfile) + "|layername=" + "test", 'test', 'ogr')
1362+
self.assertTrue(vl.isValid())
1363+
fids = set([f['fid'] for f in vl.getFeatures()])
1364+
self.assertEqual(len(fids), 1)
1365+
13471366

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

0 commit comments

Comments
 (0)