Skip to content

Commit

Permalink
Fix unreported issue with fields not retrieved for certain PG tables
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso authored and nyalldawson committed Sep 24, 2020
1 parent 69d66a1 commit 83a4c7c
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 2 deletions.
45 changes: 45 additions & 0 deletions src/providers/postgres/qgspostgresproviderconnection.cpp
Expand Up @@ -656,3 +656,48 @@ QList<QgsVectorDataProvider::NativeType> QgsPostgresProviderConnection::nativeTy
}
return types;
}


QgsFields QgsPostgresProviderConnection::fields( const QString &schema, const QString &tableName ) const
{
// Try the base implementation first and fall back to a more complex approch for the
// few PG-specific corner cases that do not work with the base implementation.
try
{
return QgsAbstractDatabaseProviderConnection::fields( schema, tableName );
}
catch ( QgsProviderConnectionException &ex )
{
// This table might expose multiple geometry columns (different geom type or SRID)
// but we are only interested in fields here, so let's pick the first one.
TableProperty tableInfo { table( schema, tableName ) };
if ( tableInfo.geometryColumnTypes().count( ) > 1 )
{
try
{
QgsDataSourceUri tUri { tableUri( schema, tableName ) };
TableProperty::GeometryColumnType geomCol { tableInfo.geometryColumnTypes().first() };
tUri.setGeometryColumn( tableInfo.geometryColumn() );
tUri.setWkbType( geomCol.wkbType );
tUri.setSrid( QString::number( geomCol.crs.postgisSrid() ) );
if ( tableInfo.primaryKeyColumns().count() > 0 )
{
tUri.setKeyColumn( tableInfo.primaryKeyColumns().first() );
}
tUri.setParam( QStringLiteral( "checkPrimaryKeyUnicity" ), QLatin1String( "0" ) );
QgsVectorLayer::LayerOptions options { true, true };
options.skipCrsValidation = true;
QgsVectorLayer vl { tUri.uri(), QStringLiteral( "temp_layer" ), mProviderKey, options };
if ( vl.isValid() )
{
return vl.fields();
}
}
catch ( QgsProviderConnectionException & )
{
// fall-through
}
}
throw ex;
}
}
3 changes: 1 addition & 2 deletions src/providers/postgres/qgspostgresproviderconnection.h
Expand Up @@ -38,6 +38,7 @@ class QgsPostgresProviderConnection : public QgsAbstractDatabaseProviderConnecti
const QMap<QString, QVariant> *options ) const override;

QString tableUri( const QString &schema, const QString &name ) const override;
QgsFields fields( const QString &schema, const QString &table ) const override;
void dropVectorTable( const QString &schema, const QString &name ) const override;
void dropRasterTable( const QString &schema, const QString &name ) const override;
void renameVectorTable( const QString &schema, const QString &name, const QString &newName ) const override;
Expand Down Expand Up @@ -65,9 +66,7 @@ class QgsPostgresProviderConnection : public QgsAbstractDatabaseProviderConnecti
void dropTablePrivate( const QString &schema, const QString &name ) const;
void renameTablePrivate( const QString &schema, const QString &name, const QString &newName ) const;


};



#endif // QGSPOSTGRESPROVIDERCONNECTION_H
24 changes: 24 additions & 0 deletions tests/src/python/test_qgsproviderconnection_postgres.py
Expand Up @@ -329,6 +329,30 @@ def test_fields(self):
fields = conn.fields('qgis_test', 'someData')
self.assertEqual(fields.names(), ['pk', 'cnt', 'name', 'name2', 'num_char', 'dt', 'date', 'time', 'geom'])

def test_fields_no_pk(self):
"""Test issue: no fields are exposed for raster_columns"""

md = QgsProviderRegistry.instance().providerMetadata('postgres')
conn = md.createConnection(self.uri, {})
fields = conn.fields("public", "raster_columns")
self.assertEqual(fields.names(), [
'r_table_catalog',
'r_table_schema',
'r_table_name',
'r_raster_column',
'srid',
'scale_x',
'scale_y',
'blocksize_x',
'blocksize_y',
'same_alignment',
'regular_blocking',
'num_bands',
'pixel_types',
'nodata_values',
'out_db',
'spatial_index'])


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

0 comments on commit 83a4c7c

Please sign in to comment.