Skip to content

Commit a2774a0

Browse files
author
Sandro Santilli
committed
Add field name in layers from postgis relation with multiple spatial fields
NOTE: only works with browser, not with "Add PostGIS Layer" dialog
1 parent b72a79a commit a2774a0

File tree

3 files changed

+44
-30
lines changed

3 files changed

+44
-30
lines changed

src/providers/postgres/qgspostgresconn.cpp

+27-24
Original file line numberDiff line numberDiff line change
@@ -270,30 +270,39 @@ void QgsPostgresConn::disconnect()
270270
deleteLater();
271271
}
272272

273-
QStringList QgsPostgresConn::pkCandidates( QString schemaName, QString viewName )
273+
/* private */
274+
void QgsPostgresConn::addColumnInfo( QgsPostgresLayerProperty& layerProperty, const QString& schemaName, const QString& viewName, bool fetchPkCandidates )
274275
{
275-
QStringList cols;
276-
277-
QString sql = QString( "SELECT attname FROM pg_attribute JOIN pg_type ON atttypid=pg_type.oid WHERE attrelid=regclass('%1.%2')" )
278-
.arg( quotedIdentifier( schemaName ) )
279-
.arg( quotedIdentifier( viewName ) );
276+
// TODO: optimize this query when pk candidates aren't needed
277+
// could use array_agg() and count()
278+
// array output would look like this: "{One,tWo}"
279+
QString sql = QString( "SELECT attname, CASE WHEN typname = ANY(ARRAY['geometry','geography','topogeometry']) THEN 1 ELSE null END AS isSpatial FROM pg_attribute JOIN pg_type ON atttypid=pg_type.oid WHERE attrelid=regclass('%1.%2')" )
280+
.arg( quotedIdentifier( schemaName ) )
281+
.arg( quotedIdentifier( viewName ) );
280282
QgsDebugMsg( sql );
281283
QgsPostgresResult colRes = PQexec( sql );
282284

285+
layerProperty.nSpCols = 0;
286+
283287
if ( colRes.PQresultStatus() == PGRES_TUPLES_OK )
284288
{
285289
for ( int i = 0; i < colRes.PQntuples(); i++ )
286290
{
287-
QgsDebugMsg( colRes.PQgetvalue( i, 0 ) );
288-
cols << colRes.PQgetvalue( i, 0 );
291+
if ( fetchPkCandidates ) {
292+
QgsDebugMsg( colRes.PQgetvalue( i, 0 ) );
293+
layerProperty.pkCols << colRes.PQgetvalue( i, 0 );
294+
}
295+
296+
if ( colRes.PQgetisnull( i, 1 ) == 0 ) {
297+
++layerProperty.nSpCols;
298+
}
289299
}
290300
}
291301
else
292302
{
293303
QgsMessageLog::logMessage( tr( "SQL:%1\nresult:%2\nerror:%3\n" ).arg( sql ).arg( colRes.PQresultStatus() ).arg( colRes.PQresultErrorMessage() ), tr( "PostGIS" ) );
294304
}
295305

296-
return cols;
297306
}
298307

299308
bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchPublicOnly, bool allowGeometrylessTables )
@@ -404,15 +413,12 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
404413
layerProperty.types = QList<QGis::WkbType>() << ( QgsPostgresConn::wkbTypeFromPostgis( type ) );
405414
layerProperty.srids = QList<int>() << srid;
406415
layerProperty.sql = "";
416+
addColumnInfo( layerProperty, schemaName, tableName, relkind == "v" );
407417

408-
if ( relkind == "v" )
418+
if ( relkind == "v" && layerProperty.pkCols.empty() )
409419
{
410-
layerProperty.pkCols = pkCandidates( schemaName, tableName );
411-
if ( layerProperty.pkCols.isEmpty() )
412-
{
413-
QgsDebugMsg( "no key columns found." );
414-
continue;
415-
}
420+
QgsDebugMsg( "no key columns found." );
421+
continue;
416422
}
417423

418424
mLayersSupported << layerProperty;
@@ -522,14 +528,11 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
522528
Q_ASSERT( !"Unknown geometry type" );
523529
}
524530

525-
if ( relkind == "v" )
531+
addColumnInfo( layerProperty, schemaName, tableName, relkind == "v" );
532+
if ( relkind == "v" && layerProperty.pkCols.empty() )
526533
{
527-
layerProperty.pkCols = pkCandidates( schemaName, tableName );
528-
if ( layerProperty.pkCols.isEmpty() )
529-
{
530-
QgsDebugMsg( "no key columns found." );
531-
continue;
532-
}
534+
QgsDebugMsg( "no key columns found." );
535+
continue;
533536
}
534537

535538
layerProperty.sql = "";
@@ -583,7 +586,7 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
583586
layerProperty.tableName = table;
584587
layerProperty.geometryColName = QString::null;
585588
layerProperty.geometryColType = sctNone;
586-
layerProperty.pkCols = relkind == "v" ? pkCandidates( schema, table ) : QStringList();
589+
addColumnInfo( layerProperty, schema, table, relkind == "v" );
587590
layerProperty.sql = "";
588591

589592
mLayersSupported << layerProperty;

src/providers/postgres/qgspostgresconn.h

+16-5
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,19 @@ struct QgsPostgresLayerProperty
5353
QgsPostgresGeometryColumnType geometryColType;
5454
QStringList pkCols;
5555
QList<int> srids;
56+
unsigned int nSpCols;
5657
QString sql;
5758

59+
60+
// TODO: rename this !
5861
int size() const { Q_ASSERT( types.size() == srids.size() ); return types.size(); }
5962

63+
QString defaultName() const {
64+
QString n = tableName;
65+
if ( nSpCols > 1 ) n += "." + geometryColName;
66+
return n;
67+
}
68+
6069
QgsPostgresLayerProperty at( int i ) const
6170
{
6271
QgsPostgresLayerProperty property;
@@ -70,6 +79,7 @@ struct QgsPostgresLayerProperty
7079
property.geometryColName = geometryColName;
7180
property.geometryColType = geometryColType;
7281
property.pkCols = pkCols;
82+
property.nSpCols = nSpCols;
7383
property.sql = sql;
7484

7585
return property;
@@ -93,14 +103,15 @@ struct QgsPostgresLayerProperty
93103
sridString += QString::number( srid );
94104
}
95105

96-
return QString( "%1.%2.%3 type=%4 srid=%5 pkCols=%6 sql=%7" )
106+
return QString( "%1.%2.%3 type=%4 srid=%5 pkCols=%6 sql=%7 nSpCols=%8" )
97107
.arg( schemaName )
98108
.arg( tableName )
99109
.arg( geometryColName )
100110
.arg( typeString )
101111
.arg( sridString )
102112
.arg( pkCols.join( "|" ) )
103-
.arg( sql );
113+
.arg( sql )
114+
.arg( nSpCols );
104115
}
105116
#endif
106117
};
@@ -215,9 +226,6 @@ class QgsPostgresConn : public QObject
215226
/** Gets information about the spatial tables */
216227
bool getTableInfo( bool searchGeometryColumnsOnly, bool searchPublicOnly, bool allowGeometrylessTables );
217228

218-
/** get primary key candidates (all int4 columns) */
219-
QStringList pkCandidates( QString schemaName, QString viewName );
220-
221229
qint64 getBinaryInt( QgsPostgresResult &queryResult, int row, int col );
222230

223231
QString fieldExpression( const QgsField &fld );
@@ -292,6 +300,9 @@ class QgsPostgresConn : public QObject
292300
static QMap<QString, QgsPostgresConn *> sConnectionsRW;
293301
static QMap<QString, QgsPostgresConn *> sConnectionsRO;
294302

303+
/** count number of spatial columns in a given relation */
304+
void addColumnInfo( QgsPostgresLayerProperty& layerProperty, const QString& schemaName, const QString& viewName, bool fetchPkCandidates );
305+
295306
//! List of the supported layers
296307
QVector<QgsPostgresLayerProperty> mLayersSupported;
297308

src/providers/postgres/qgspostgresdataitems.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ void QgsPGSchemaItem::addLayer( QgsPostgresLayerProperty layerProperty )
375375
tip = tr( "as geometryless table" );
376376
}
377377

378-
QgsPGLayerItem *layerItem = new QgsPGLayerItem( this, layerProperty.tableName, mPath + "/" + layerProperty.tableName, layerType, layerProperty );
378+
QgsPGLayerItem *layerItem = new QgsPGLayerItem( this, layerProperty.defaultName(), mPath + "/" + layerProperty.tableName, layerType, layerProperty );
379379
layerItem->setToolTip( tip );
380380
addChild( layerItem );
381381
}

0 commit comments

Comments
 (0)