Skip to content

Commit

Permalink
Merge pull request #9219 from elpaso/bugfix-21303-postgis-slow-table-…
Browse files Browse the repository at this point in the history
…open

Postgis: cache information about enum fields
  • Loading branch information
elpaso committed Feb 21, 2019
2 parents 17280c3 + 7627fb2 commit e42c6a3
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
51 changes: 44 additions & 7 deletions src/providers/postgres/qgspostgresprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) );
Expand Down Expand Up @@ -1683,42 +1687,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 );
}
}
}
Expand Down Expand Up @@ -5169,3 +5181,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;
}

6 changes: 6 additions & 0 deletions src/providers/postgres/qgspostgresprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -530,6 +535,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
Expand Down

0 comments on commit e42c6a3

Please sign in to comment.