From 87f4410ee0d4660e54f85ee1a1a07bcd8baffe94 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 6 May 2019 22:33:37 +0200 Subject: [PATCH] [OGR provider] Fix opening of GeoPackage datasets with foreign key violation --- src/providers/ogr/qgsogrprovider.cpp | 10 ++++++++++ tests/src/python/test_provider_ogr_gpkg.py | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/providers/ogr/qgsogrprovider.cpp b/src/providers/ogr/qgsogrprovider.cpp index 784ee52c2926..5a8ff5a6dd96 100644 --- a/src/providers/ogr/qgsogrprovider.cpp +++ b/src/providers/ogr/qgsogrprovider.cpp @@ -3938,11 +3938,21 @@ GDALDatasetH QgsOgrProviderUtils::GDALOpenWrapper( const char *pszPath, bool bUp bIsLocalGpkg = true; } + bool modify_OGR_GPKG_FOREIGN_KEY_CHECK = !CPLGetConfigOption( "OGR_GPKG_FOREIGN_KEY_CHECK", nullptr ); + if ( modify_OGR_GPKG_FOREIGN_KEY_CHECK ) + { + CPLSetThreadLocalConfigOption( "OGR_GPKG_FOREIGN_KEY_CHECK", "NO" ); + } + const int nOpenFlags = GDAL_OF_VECTOR | ( bUpdate ? GDAL_OF_UPDATE : 0 ); GDALDatasetH hDS = GDALOpenEx( pszPath, nOpenFlags, nullptr, papszOpenOptions, nullptr ); CSLDestroy( papszOpenOptions ); CPLSetThreadLocalConfigOption( "OGR_SQLITE_JOURNAL", nullptr ); + if ( modify_OGR_GPKG_FOREIGN_KEY_CHECK ) + { + CPLSetThreadLocalConfigOption( "OGR_GPKG_FOREIGN_KEY_CHECK", nullptr ); + } if ( !hDS ) { diff --git a/tests/src/python/test_provider_ogr_gpkg.py b/tests/src/python/test_provider_ogr_gpkg.py index 7e8d758f136a..9c4385f172e3 100644 --- a/tests/src/python/test_provider_ogr_gpkg.py +++ b/tests/src/python/test_provider_ogr_gpkg.py @@ -1344,6 +1344,25 @@ def testUniqueValuesOnFidColumn(self): self.assertEqual(vl1.uniqueValues(0), {1, 2}) self.assertEqual(vl1.uniqueValues(1), {'one', 'two'}) + def testForeignKeyViolation(self): + """Test that we can open a dataset with a foreign key violation""" + + tmpfile = os.path.join(self.basetestpath, 'testForeignKeyViolation.gpkg') + ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile) + lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint) + f = ogr.Feature(lyr.GetLayerDefn()) + f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 1)')) + lyr.CreateFeature(f) + ds.ExecuteSQL("PRAGMA foreign_keys = OFF") + ds.ExecuteSQL("CREATE TABLE foo(id INTEGER)") + ds.ExecuteSQL("CREATE TABLE bar(fkey INTEGER, CONSTRAINT fkey_constraint FOREIGN KEY (fkey) REFERENCES foo(id))") + ds.ExecuteSQL("INSERT INTO bar VALUES (1)") + ds = None + vl = QgsVectorLayer('{}'.format(tmpfile) + "|layername=" + "test", 'test', 'ogr') + self.assertTrue(vl.isValid()) + fids = set([f['fid'] for f in vl.getFeatures()]) + self.assertEqual(len(fids), 1) + if __name__ == '__main__': unittest.main()