Skip to content
Permalink
Browse files

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.
  • Loading branch information
elpaso committed Feb 20, 2019
1 parent e5a416e commit 4f30a44be2d59a00169da8ba982d0e95d8e9e2a2
Showing with 39 additions and 7 deletions.
  1. +34 −7 src/providers/postgres/qgspostgresprovider.cpp
  2. +5 −0 src/providers/postgres/qgspostgresprovider.h
@@ -1683,42 +1683,50 @@ 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
{
//is there a domain check constraint for the attribute?
if ( !parseDomainCheckConstraint( enumList, fieldName ) )
{
enumList.clear();
mShared->setFieldSupportsEnumValues( index, false );
}
}
}
@@ -5166,3 +5174,22 @@ void QgsPostgresSharedData::clear()
mFeaturesCounted = -1;
mFidCounter = 0;
}

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

@@ -522,6 +522,10 @@ class QgsPostgresSharedData
QVariantList lookupKey( QgsFeatureId featureId );
void clear();

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 +534,7 @@ class QgsPostgresSharedData
QgsFeatureId mFidCounter = 0; // next feature id if map is used
QMap<QVariantList, QgsFeatureId> mKeyToFid; // map key values to feature id
QMap<QgsFeatureId, QVariantList> mFidToKey; // map feature id back to key values
QMap<int, bool> mFieldSupportsEnumValues; // map field index to bool flag supports enum values
};

// clazy:excludeall=qstring-allocations

0 comments on commit 4f30a44

Please sign in to comment.
You can’t perform that action at this time.