Skip to content
Permalink
Browse files

PG: accept duplicated fields for query layers

Fixes #38976
  • Loading branch information
elpaso committed Sep 23, 2020
1 parent 9880a75 commit dd64c6d2a793145d15546186744ece9ac76abd03
Showing with 31 additions and 1 deletion.
  1. +14 −1 src/providers/postgres/qgspostgresprovider.cpp
  2. +17 −0 tests/src/python/test_provider_postgres.py
@@ -1175,11 +1175,24 @@ bool QgsPostgresProvider::loadFields()
if ( fields.contains( fieldName ) )
{
QgsMessageLog::logMessage( tr( "Duplicate field %1 found\n" ).arg( fieldName ), tr( "PostGIS" ) );
// In case of read-only query layers we can safely ignore the issue
// In case of read-only query layers we can safely ignore the issue and rename the duplicated field
if ( ! mIsQuery )
{
return false;
}
else
{
unsigned short int i = 1;
while ( i < std::numeric_limits<unsigned short int>::max() )
{
const QString newName { QStringLiteral( "%1 (%2)" ).arg( fieldName ).arg( ++i ) };
if ( ! fields.contains( newName ) )
{
fieldName = newName;
break;
}
}
}
}

fields << fieldName;
@@ -3021,6 +3021,23 @@ def testTrustFlag(self):
vl = p.mapLayersByName('testTrustFlag')[0]
self.assertTrue(vl.isValid())

def testQueryLayerDuplicatedFields(self):
"""Test that duplicated fields from a query layer are returned"""

def _get_layer(sql):
return QgsVectorLayer(
self.dbconn +
' sslmode=disable key=\'__rid__\' table=\'(SELECT row_number() OVER () AS __rid__, * FROM (' + sql + ') as foo)\' sql=',
'test', 'postgres')

l = _get_layer('SELECT 1, 2')
self.assertEqual(l.fields().count(), 3)
self.assertEqual([f.name() for f in l.fields()], ['__rid__', '?column?', '?column? (2)'])

l = _get_layer('SELECT 1 as id, 2 as id')
self.assertEqual(l.fields().count(), 3)
self.assertEqual([f.name() for f in l.fields()], ['__rid__', 'id', 'id (2)'])


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

0 comments on commit dd64c6d

Please sign in to comment.
You can’t perform that action at this time.