Skip to content

Commit 4f30a44

Browse files
committedFeb 20, 2019
Postgis: cache information about enum fields
This is called several times and can slow down substantially the opening of the attribute table. Partially fixes #21303 (down from ~30 to ~6 seconds on a remote connection) The remaining ~4 seconds (compared to ~2 seconds in 2.18) are due to the check for enums and provider-side constraints, that were not implemented in 2.18. See: QgsEnumerationWidgetFactory::fieldScore and the call to enumValues for details, fieldScore is called several times because QgsAttributeTableModel::loadAttributes is also called multiple times and it queries for widget configuration all the times.
1 parent e5a416e commit 4f30a44

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed
 

‎src/providers/postgres/qgspostgresprovider.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,42 +1683,50 @@ QStringList QgsPostgresProvider::uniqueStringsMatching( int index, const QString
16831683

16841684
void QgsPostgresProvider::enumValues( int index, QStringList &enumList ) const
16851685
{
1686-
enumList.clear();
16871686

16881687
if ( index < 0 || index >= mAttributeFields.count() )
16891688
return;
16901689

1690+
if ( ! mShared->fieldSupportsEnumValuesIsSet( index ) )
1691+
{
1692+
mShared->setFieldSupportsEnumValues( index, true );
1693+
}
1694+
else if ( ! mShared->fieldSupportsEnumValues( index ) )
1695+
{
1696+
return;
1697+
}
1698+
16911699
//find out type of index
1692-
QString fieldName = mAttributeFields.at( index ).name();
1700+
const QString fieldName = mAttributeFields.at( index ).name();
16931701
QString typeName = mAttributeFields.at( index ).typeName();
16941702

16951703
// Remove schema extension from typeName
16961704
typeName.remove( QRegularExpression( "^([^.]+\\.)+" ) );
16971705

16981706
//is type an enum?
1699-
QString typeSql = QStringLiteral( "SELECT typtype FROM pg_type WHERE typname=%1" ).arg( quotedValue( typeName ) );
1707+
const QString typeSql = QStringLiteral( "SELECT typtype FROM pg_type WHERE typname=%1" ).arg( quotedValue( typeName ) );
17001708
QgsPostgresResult typeRes( connectionRO()->PQexec( typeSql ) );
17011709
if ( typeRes.PQresultStatus() != PGRES_TUPLES_OK || typeRes.PQntuples() < 1 )
17021710
{
1711+
mShared->setFieldSupportsEnumValues( index, false );
17031712
return;
17041713
}
17051714

1706-
1707-
QString typtype = typeRes.PQgetvalue( 0, 0 );
1715+
const QString typtype = typeRes.PQgetvalue( 0, 0 );
17081716
if ( typtype.compare( QLatin1String( "e" ), Qt::CaseInsensitive ) == 0 )
17091717
{
17101718
//try to read enum_range of attribute
17111719
if ( !parseEnumRange( enumList, fieldName ) )
17121720
{
1713-
enumList.clear();
1721+
mShared->setFieldSupportsEnumValues( index, false );
17141722
}
17151723
}
17161724
else
17171725
{
17181726
//is there a domain check constraint for the attribute?
17191727
if ( !parseDomainCheckConstraint( enumList, fieldName ) )
17201728
{
1721-
enumList.clear();
1729+
mShared->setFieldSupportsEnumValues( index, false );
17221730
}
17231731
}
17241732
}
@@ -5166,3 +5174,22 @@ void QgsPostgresSharedData::clear()
51665174
mFeaturesCounted = -1;
51675175
mFidCounter = 0;
51685176
}
5177+
5178+
bool QgsPostgresSharedData::fieldSupportsEnumValuesIsSet( int index )
5179+
{
5180+
QMutexLocker locker( &mMutex );
5181+
return mFieldSupportsEnumValues.contains( index );
5182+
}
5183+
5184+
bool QgsPostgresSharedData::fieldSupportsEnumValues( int index )
5185+
{
5186+
QMutexLocker locker( &mMutex );
5187+
return mFieldSupportsEnumValues.contains( index ) && mFieldSupportsEnumValues[ index ];
5188+
}
5189+
5190+
void QgsPostgresSharedData::setFieldSupportsEnumValues( int index, bool isSupported )
5191+
{
5192+
QMutexLocker locker( &mMutex );
5193+
mFieldSupportsEnumValues[ index ] = isSupported;
5194+
}
5195+

‎src/providers/postgres/qgspostgresprovider.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,10 @@ class QgsPostgresSharedData
522522
QVariantList lookupKey( QgsFeatureId featureId );
523523
void clear();
524524

525+
bool fieldSupportsEnumValuesIsSet( int index );
526+
bool fieldSupportsEnumValues( int index );
527+
void setFieldSupportsEnumValues( int index, bool isSupported );
528+
525529
protected:
526530
QMutex mMutex; //!< Access to all data members is guarded by the mutex
527531

@@ -530,6 +534,7 @@ class QgsPostgresSharedData
530534
QgsFeatureId mFidCounter = 0; // next feature id if map is used
531535
QMap<QVariantList, QgsFeatureId> mKeyToFid; // map key values to feature id
532536
QMap<QgsFeatureId, QVariantList> mFidToKey; // map feature id back to key values
537+
QMap<int, bool> mFieldSupportsEnumValues; // map field index to bool flag supports enum values
533538
};
534539

535540
// clazy:excludeall=qstring-allocations

0 commit comments

Comments
 (0)
Please sign in to comment.