Skip to content

Commit

Permalink
More tests for checkPrimaryKeyUnicity
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Apr 26, 2019
1 parent 38c91e4 commit 163082a
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 6 deletions.
17 changes: 17 additions & 0 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,23 @@ bool QgsVectorLayer::setDataProvider( QString const &provider, const QgsDataProv
{
mProviderKey = provider;
delete mDataProvider;

// For Postgres provider primary key unicity is tested at construction time,
// so it has to be set before initializing the provider,
// this manipulation is necessary to preserve default behavior when
// "trust layer metadata" project level option is set and checkPrimaryKeyUnicity
// was not explicitely passed in the uri
if ( provider.compare( QLatin1String( "postgres" ) ) == 0 )
{
const QString checkUnicityKey { QStringLiteral( "checkPrimaryKeyUnicity" ) };
QgsDataSourceUri uri( mDataSource );
if ( ! uri.hasParam( checkUnicityKey ) )
{
uri.setParam( checkUnicityKey, mReadExtentFromXml ? "0" : "1" );
mDataSource = uri.uri( false );
}
}

mDataProvider = qobject_cast<QgsVectorDataProvider *>( QgsProviderRegistry::instance()->createProvider( provider, mDataSource, options ) );
if ( !mDataProvider )
{
Expand Down
2 changes: 1 addition & 1 deletion src/providers/postgres/qgspgtablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void QgsPgTableModel::addTableEntry( const QgsPostgresLayerProperty &layerProper
checkPkUnicityItem->setFlags( checkPkUnicityItem->flags() | Qt::ItemIsUserCheckable );

// Legacy: default value is determined by project option to trust layer's metadata
// TODO: remove this default from QGIS 4 and leave default value to false
// TODO: remove this default from QGIS 4 and leave default value to false?
// checkPkUnicity has only effect on views and materialized views, so we can safely disable it
if ( layerProperty.isView || layerProperty.isMaterializedView )
{
Expand Down
1 change: 1 addition & 0 deletions src/providers/postgres/qgspostgresprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ QgsPostgresProvider::QgsPostgresProvider( QString const &uri, const ProviderOpti

if ( mUri.hasParam( QStringLiteral( "checkPrimaryKeyUnicity" ) ) )
{

if ( mUri.param( QStringLiteral( "checkPrimaryKeyUnicity" ) ).compare( QLatin1String( "0" ) ) == 0 )
{
mCheckPrimaryKeyUnicity = false;
Expand Down
18 changes: 17 additions & 1 deletion tests/src/python/test_provider_postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -1104,14 +1104,30 @@ def testCheckPkUnicityOnView(self):
vl0 = QgsVectorLayer(self.dbconn + ' checkPrimaryKeyUnicity=\'0\' sslmode=disable key=\'pk\' srid=0 type=POINT table="qgis_test"."b21839_pk_unicity_view" (geom) sql=', 'test', 'postgres')
self.assertTrue(vl0.isValid())

geom = vl0.getFeature(1).geometry().asWkt()

# This is NOT valid
vl0 = QgsVectorLayer(self.dbconn + ' checkPrimaryKeyUnicity=\'1\' sslmode=disable key=\'an_int\' srid=0 type=POINT table="qgis_test"."b21839_pk_unicity_view" (geom) sql=', 'test', 'postgres')
self.assertFalse(vl0.isValid())

# This is valid because the default is to not check unicity
# This is NOT valid because the default is to check unicity
vl0 = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'an_int\' srid=0 type=POINT table="qgis_test"."b21839_pk_unicity_view" (geom) sql=', 'test', 'postgres')
self.assertFalse(vl0.isValid())

# This is valid because the readExtentFromXml option is set
options = QgsVectorLayer.LayerOptions(True, True) # loadDefaultStyle, readExtentFromXml
vl0 = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'an_int\' srid=0 type=POINT table="qgis_test"."b21839_pk_unicity_view" (geom) sql=', 'test', 'postgres', options)
self.assertTrue(vl0.isValid())

# Valid because a_unique_int is unique
vl0 = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'a_unique_int\' srid=0 type=POINT table="qgis_test"."b21839_pk_unicity_view" (geom) sql=', 'test', 'postgres')
self.assertEqual(vl0.getFeature(1).geometry().asWkt(), geom)

# Valid because a_unique_int is unique
vl0 = QgsVectorLayer(self.dbconn + ' checkPrimaryKeyUnicity=\'1\' sslmode=disable key=\'a_unique_int\' srid=0 type=POINT table="qgis_test"."b21839_pk_unicity_view" (geom) sql=', 'test', 'postgres')
self.assertTrue(vl0.isValid())
self.assertEqual(vl0.getFeature(1).geometry().asWkt(), geom)

def testNotify(self):
vl0 = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POLYGON table="qgis_test"."some_poly_data" (geom) sql=', 'test', 'postgres')
vl0.dataProvider().setListening(True)
Expand Down
10 changes: 6 additions & 4 deletions tests/testdata/provider/testdata_pg.sql
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ CREATE TABLE qgis_test.b21839_pk_unicity
(
pk serial NOT NULL,
an_int integer NOT NULL,
a_unique_int integer NOT NULL,
geom geometry(Point),
CONSTRAINT b21839_pk_unicity_pkey PRIMARY KEY (pk)
)
Expand All @@ -557,19 +558,20 @@ WITH (


INSERT INTO qgis_test.b21839_pk_unicity(
pk, an_int, geom)
VALUES (1, 1, ST_GeomFromText('point( 1 1)'));
pk, an_int, a_unique_int , geom)
VALUES (1, 1, 1, ST_GeomFromText('point( 1 1)'));


INSERT INTO qgis_test.b21839_pk_unicity(
pk, an_int, geom)
VALUES (2, 1, ST_GeomFromText('point( 1 3)'));
pk, an_int, a_unique_int, geom)
VALUES (2, 1, 2, ST_GeomFromText('point( 1 3)'));



CREATE OR REPLACE VIEW qgis_test.b21839_pk_unicity_view AS
SELECT b21839_pk_unicity.pk,
b21839_pk_unicity.an_int,
b21839_pk_unicity.a_unique_int,
b21839_pk_unicity.geom
FROM qgis_test.b21839_pk_unicity;

0 comments on commit 163082a

Please sign in to comment.