Skip to content

Commit

Permalink
fix discovering relation when a table has relation with several layers
Browse files Browse the repository at this point in the history
  • Loading branch information
speillet authored and nyalldawson committed Jan 27, 2021
1 parent 1047110 commit c75e160
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -4989,6 +4989,7 @@ QList<QgsRelation> QgsPostgresProvider::discoverRelations( const QgsVectorLayer
}

int nbFound = 0;
QList<QString> refTableFound;
for ( int row = 0; row < sqlResult.PQntuples(); ++row )
{
const QString name = sqlResult.PQgetvalue( row, 0 );
Expand All @@ -5006,7 +5007,7 @@ QList<QgsRelation> QgsPostgresProvider::discoverRelations( const QgsVectorLayer
}
const QString refColumn = sqlResult.PQgetvalue( row, 4 );
const QString position = sqlResult.PQgetvalue( row, 5 );
if ( ( position == QLatin1String( "1" ) ) || ( nbFound == 0 ) )
if ( ( position == QLatin1String( "1" ) ) || ( nbFound == 0 ) || ( !refTableFound.contains( refTable ) ) )
{
// first reference field => try to find if we have layers for the referenced table
const QList<QgsVectorLayer *> foundLayers = searchLayers( layers, mUri.connectionInfo( false ), refSchema, refTable );
Expand All @@ -5023,6 +5024,7 @@ QList<QgsRelation> QgsPostgresProvider::discoverRelations( const QgsVectorLayer
{
result.append( relation );
++nbFound;
refTableFound.append( refTable );
}
else
{
Expand Down
25 changes: 25 additions & 0 deletions tests/src/python/test_provider_postgres.py
Expand Up @@ -2286,6 +2286,31 @@ def testInvalidLayerDiscoverRelations(self):
self.assertFalse(vl.isValid())
self.assertEqual(vl.dataProvider().discoverRelations(vl, []), [])

def testValidLayerDiscoverRelations(self):
vl = QgsVectorLayer(
self.dbconn +
' sslmode=disable key=\'pk\' checkPrimaryKeyUnicity=\'1\' table="qgis_test"."referencing_layer"',
'referencing_layer', 'postgres')
vls = [
QgsVectorLayer(
self.dbconn +
' sslmode=disable key=\'pk_ref_1\' checkPrimaryKeyUnicity=\'1\' table="qgis_test"."referenced_layer_1"',
'referenced_layer_1', 'postgres'),
QgsVectorLayer(
self.dbconn +
' sslmode=disable key=\'pk_ref_2\' checkPrimaryKeyUnicity=\'1\' table="qgis_test"."referenced_layer_2"',
'referenced_layer_2', 'postgres'),
vl
]

for lyr in vls:
self.assertTrue(lyr.isValid())
QgsProject.instance().addMapLayer(lyr)
relations = vl.dataProvider().discoverRelations(vl, vls)
self.assertEqual(len(relations), 2)
for i, r in enumerate(relations):
self.assertEqual(r.referencedLayer(), vls[i])

def testCheckTidPkOnViews(self):
"""Test vector layer based on a view with `ctid` as a key"""

Expand Down
24 changes: 24 additions & 0 deletions tests/testdata/provider/testdata_pg.sql
Expand Up @@ -721,3 +721,27 @@ CREATE TABLE IF NOT EXISTS "test_check_constraint" (
INSERT INTO test_check_constraint (geom, i_will_fail_on_no_name)
VALUES ('SRID=4326;POINT(9 45)'::geometry, 'I have a name'), ('SRID=4326;POINT(10 46)'::geometry, 'I have a name too');

---------------------------------------------
--
-- Tables to check tables relation in project
--

CREATE TABLE qgis_test.referenced_layer_1(
pk_ref_1 serial primary key
);

CREATE TABLE qgis_test.referenced_layer_2(
pk_ref_2 serial primary key
);

CREATE TABLE qgis_test.referencing_layer(
pk serial primary key,
fk_ref_1 integer,
fk_ref_2 integer,
CONSTRAINT fk_ref_1
FOREIGN KEY(fk_ref_1)
REFERENCES qgis_test.referenced_layer_1(pk_ref_1),
CONSTRAINT fk_ref_2
FOREIGN KEY(fk_ref_2)
REFERENCES qgis_test.referenced_layer_2(pk_ref_2)
);

0 comments on commit c75e160

Please sign in to comment.