diff --git a/src/providers/postgres/qgspostgresprovider.cpp b/src/providers/postgres/qgspostgresprovider.cpp index 6eae624002fc..3a2e10931399 100644 --- a/src/providers/postgres/qgspostgresprovider.cpp +++ b/src/providers/postgres/qgspostgresprovider.cpp @@ -711,6 +711,10 @@ struct PGTypeInfo bool QgsPostgresProvider::loadFields() { + + // Clear cached information about enum values support + mShared->clearSupportsEnumValuesCache(); + if ( !mIsQuery ) { QgsDebugMsg( QStringLiteral( "Loading fields for table %1" ).arg( mTableName ) ); @@ -1683,34 +1687,42 @@ QStringList QgsPostgresProvider::uniqueStringsMatching( int index, const QString void QgsPostgresProvider::enumValues( int index, QStringList &enumList ) const { - enumList.clear(); if ( index < 0 || index >= mAttributeFields.count() ) return; + if ( ! mShared->fieldSupportsEnumValuesIsSet( index ) ) + { + mShared->setFieldSupportsEnumValues( index, true ); + } + else if ( ! mShared->fieldSupportsEnumValues( index ) ) + { + return; + } + //find out type of index - QString fieldName = mAttributeFields.at( index ).name(); + const QString fieldName = mAttributeFields.at( index ).name(); QString typeName = mAttributeFields.at( index ).typeName(); // Remove schema extension from typeName typeName.remove( QRegularExpression( "^([^.]+\\.)+" ) ); //is type an enum? - QString typeSql = QStringLiteral( "SELECT typtype FROM pg_type WHERE typname=%1" ).arg( quotedValue( typeName ) ); + const QString typeSql = QStringLiteral( "SELECT typtype FROM pg_type WHERE typname=%1" ).arg( quotedValue( typeName ) ); QgsPostgresResult typeRes( connectionRO()->PQexec( typeSql ) ); if ( typeRes.PQresultStatus() != PGRES_TUPLES_OK || typeRes.PQntuples() < 1 ) { + mShared->setFieldSupportsEnumValues( index, false ); return; } - - QString typtype = typeRes.PQgetvalue( 0, 0 ); + const QString typtype = typeRes.PQgetvalue( 0, 0 ); if ( typtype.compare( QLatin1String( "e" ), Qt::CaseInsensitive ) == 0 ) { //try to read enum_range of attribute if ( !parseEnumRange( enumList, fieldName ) ) { - enumList.clear(); + mShared->setFieldSupportsEnumValues( index, false ); } } else @@ -1718,7 +1730,7 @@ void QgsPostgresProvider::enumValues( int index, QStringList &enumList ) const //is there a domain check constraint for the attribute? if ( !parseDomainCheckConstraint( enumList, fieldName ) ) { - enumList.clear(); + mShared->setFieldSupportsEnumValues( index, false ); } } } @@ -5166,3 +5178,28 @@ void QgsPostgresSharedData::clear() mFeaturesCounted = -1; mFidCounter = 0; } + +void QgsPostgresSharedData::clearSupportsEnumValuesCache() +{ + QMutexLocker locker( &mMutex ); + mFieldSupportsEnumValues.clear(); +} + +bool QgsPostgresSharedData::fieldSupportsEnumValuesIsSet( int index ) +{ + QMutexLocker locker( &mMutex ); + return mFieldSupportsEnumValues.contains( index ); +} + +bool QgsPostgresSharedData::fieldSupportsEnumValues( int index ) +{ + QMutexLocker locker( &mMutex ); + return mFieldSupportsEnumValues.contains( index ) && mFieldSupportsEnumValues[ index ]; +} + +void QgsPostgresSharedData::setFieldSupportsEnumValues( int index, bool isSupported ) +{ + QMutexLocker locker( &mMutex ); + mFieldSupportsEnumValues[ index ] = isSupported; +} + diff --git a/src/providers/postgres/qgspostgresprovider.h b/src/providers/postgres/qgspostgresprovider.h index 824b19a94db7..e489e4cf5cf0 100644 --- a/src/providers/postgres/qgspostgresprovider.h +++ b/src/providers/postgres/qgspostgresprovider.h @@ -522,6 +522,11 @@ class QgsPostgresSharedData QVariantList lookupKey( QgsFeatureId featureId ); void clear(); + void clearSupportsEnumValuesCache( ); + bool fieldSupportsEnumValuesIsSet( int index ); + bool fieldSupportsEnumValues( int index ); + void setFieldSupportsEnumValues( int index, bool isSupported ); + protected: QMutex mMutex; //!< Access to all data members is guarded by the mutex @@ -530,6 +535,7 @@ class QgsPostgresSharedData QgsFeatureId mFidCounter = 0; // next feature id if map is used QMap mKeyToFid; // map key values to feature id QMap mFidToKey; // map feature id back to key values + QMap mFieldSupportsEnumValues; // map field index to bool flag supports enum values }; // clazy:excludeall=qstring-allocations