Fix unreported issue with fields not retrieved for certain PG tables

This commit is contained in:
Alessandro Pasotti 2020-09-22 11:29:00 +02:00 committed by Nyall Dawson
parent 69d66a121d
commit 83a4c7cde3
3 changed files with 70 additions and 2 deletions

View File

@ -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;
}
}

View File

@ -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;
@ -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

View File

@ -329,6 +329,30 @@ IMPORT FOREIGN SCHEMA qgis_test LIMIT TO ( "someData" )
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()