Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Revert "postgres provider: performance improvements when loading layers"
This reverts commit 2220b86.

The commit broke existing unit tests
  • Loading branch information
nyalldawson committed May 20, 2019
1 parent ac5e945 commit bf13d09
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 63 deletions.
5 changes: 3 additions & 2 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -773,14 +773,15 @@ QgsRectangle QgsVectorLayer::extent() const
if ( !isSpatial() )
return rect;


if ( !mValidExtent && mLazyExtent && mDataProvider && !mDataProvider->hasMetadata() && mReadExtentFromXml && !mXmlExtent.isNull() )
{
mExtent = mXmlExtent;
mValidExtent = true;
mLazyExtent = false;
}

if ( !mValidExtent && mLazyExtent && !mReadExtentFromXml && mDataProvider && mDataProvider->isValid() )
if ( !mValidExtent && mLazyExtent && mDataProvider && mDataProvider->isValid() )
{
// get the extent
QgsRectangle mbr = mDataProvider->extent();
Expand Down Expand Up @@ -811,7 +812,7 @@ QgsRectangle QgsVectorLayer::extent() const

// get the extent of the layer from the provider
// but only when there are some features already
if ( !mReadExtentFromXml && mDataProvider->featureCount() != 0 )
if ( mDataProvider->featureCount() != 0 )
{
QgsRectangle r = mDataProvider->extent();
rect.combineExtentWith( r );
Expand Down
32 changes: 2 additions & 30 deletions src/providers/postgres/qgspostgresconn.cpp
Expand Up @@ -149,9 +149,8 @@ QgsPostgresConn *QgsPostgresConn::connectDb( const QString &conninfo, bool reado

// This is called from may places where shared parameter cannot be forced to false (QgsVectorLayerExporter)
// and which is run in a different thread (drag and drop in browser)
if ( shared && QApplication::instance()->thread() != QThread::currentThread() )
if ( QApplication::instance()->thread() != QThread::currentThread() )
{
QgsDebugMsg( QStringLiteral( "Connection cannot be shared between threads" ) );
shared = false;
}

Expand All @@ -170,6 +169,7 @@ QgsPostgresConn *QgsPostgresConn::connectDb( const QString &conninfo, bool reado
}

QgsPostgresConn *conn = new QgsPostgresConn( conninfo, readonly, shared, transaction );

if ( conn->mRef == 0 )
{
delete conn;
Expand Down Expand Up @@ -1933,31 +1933,3 @@ QString QgsPostgresConn::currentDatabase() const

return database;
}

const QgsPostgresConn::PGTypeInfo &QgsPostgresConn::type( int oid ) const
{
if ( mTypeMap.isEmpty() )
{
QMutexLocker locker( &mLock );
if ( mTypeMap.isEmpty() )
{
QString sql = QStringLiteral( "SELECT oid,typname,typtype,typelem,typlen FROM pg_type" );
QgsPostgresResult typeResult( PQexec( sql ) );

for ( int i = 0; i < typeResult.PQntuples(); ++i )
{
PGTypeInfo typeInfo =
{
/* typeName = */ typeResult.PQgetvalue( i, 1 ),
/* typeType = */ typeResult.PQgetvalue( i, 2 ),
/* typeElem = */ typeResult.PQgetvalue( i, 3 ),
/* typeLen = */ typeResult.PQgetvalue( i, 4 ).toInt()
};
mTypeMap.insert( typeResult.PQgetvalue( i, 0 ).toInt(), typeInfo );
}
QgsDebugMsg( "types retrieved" );
}
}

return mTypeMap[oid];
}
12 changes: 0 additions & 12 deletions src/providers/postgres/qgspostgresconn.h
Expand Up @@ -364,16 +364,6 @@ class QgsPostgresConn : public QObject
void lock() { mLock.lock(); }
void unlock() { mLock.unlock(); }

struct PGTypeInfo
{
QString typeName;
QString typeType;
QString typeElem;
int typeLen;
};

const PGTypeInfo &type( int oid ) const;

private:
QgsPostgresConn( const QString &conninfo, bool readOnly, bool shared, bool transaction );
~QgsPostgresConn() override;
Expand Down Expand Up @@ -446,8 +436,6 @@ class QgsPostgresConn : public QObject

bool mTransaction;

mutable QMap<int, PGTypeInfo> mTypeMap;

mutable QMutex mLock;
};

Expand Down
65 changes: 49 additions & 16 deletions src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -106,6 +106,19 @@ QgsPostgresProvider::QgsPostgresProvider( QString const &uri, const ProviderOpti
mRequestedSrid = mUri.srid();
mRequestedGeomType = mUri.wkbType();

if ( mUri.hasParam( QStringLiteral( "checkPrimaryKeyUnicity" ) ) )
{

if ( mUri.param( QStringLiteral( "checkPrimaryKeyUnicity" ) ).compare( QLatin1String( "0" ) ) == 0 )
{
mCheckPrimaryKeyUnicity = false;
}
else
{
mCheckPrimaryKeyUnicity = true;
}
}

if ( mSchemaName.isEmpty() && mTableName.startsWith( '(' ) && mTableName.endsWith( ')' ) )
{
mIsQuery = true;
Expand All @@ -130,15 +143,12 @@ QgsPostgresProvider::QgsPostgresProvider( QString const &uri, const ProviderOpti
mUseEstimatedMetadata = mUri.useEstimatedMetadata();
mSelectAtIdDisabled = mUri.selectAtIdDisabled();

mCheckPrimaryKeyUnicity = !mUri.hasParam( QStringLiteral( "checkPrimaryKeyUnicity" ) ) || mUri.param( QStringLiteral( "checkPrimaryKeyUnicity" ) ).compare( QLatin1String( "0" ) ) != 0;

QgsDebugMsg( QStringLiteral( "Connection info is %1" ).arg( mUri.connectionInfo( false ) ) );
QgsDebugMsg( QStringLiteral( "Geometry column is: %1" ).arg( mGeometryColumn ) );
QgsDebugMsg( QStringLiteral( "Schema is: %1" ).arg( mSchemaName ) );
QgsDebugMsg( QStringLiteral( "Table name is: %1" ).arg( mTableName ) );
QgsDebugMsg( QStringLiteral( "Query is: %1" ).arg( mQuery ) );
QgsDebugMsg( QStringLiteral( "Where clause is: %1" ).arg( mSqlWhereClause ) );
QgsDebugMsg( QStringLiteral( "Using estimated metadata: %1" ).arg( mUseEstimatedMetadata ) );

// no table/query passed, the provider could be used to get tables
if ( mQuery.isEmpty() )
Expand Down Expand Up @@ -695,6 +705,14 @@ QString QgsPostgresProvider::endianString()
}


struct PGTypeInfo
{
QString typeName;
QString typeType;
QString typeElem;
int typeLen;
};

bool QgsPostgresProvider::loadFields()
{

Expand Down Expand Up @@ -726,6 +744,24 @@ bool QgsPostgresProvider::loadFields()

QgsPostgresResult result( connectionRO()->PQexec( sql ) );

// Collect type info
sql = QStringLiteral( "SELECT oid,typname,typtype,typelem,typlen FROM pg_type" );
QgsPostgresResult typeResult( connectionRO()->PQexec( sql ) );

QMap<int, PGTypeInfo> typeMap;
for ( int i = 0; i < typeResult.PQntuples(); ++i )
{
PGTypeInfo typeInfo =
{
/* typeName = */ typeResult.PQgetvalue( i, 1 ),
/* typeType = */ typeResult.PQgetvalue( i, 2 ),
/* typeElem = */ typeResult.PQgetvalue( i, 3 ),
/* typeLen = */ typeResult.PQgetvalue( i, 4 ).toInt()
};
typeMap.insert( typeResult.PQgetvalue( i, 0 ).toInt(), typeInfo );
}


QMap<int, QMap<int, QString> > fmtFieldTypeMap, descrMap, defValMap, identityMap;
QMap<int, QMap<int, int> > attTypeIdMap;
QMap<int, QMap<int, bool> > notNullMap, uniqueMap;
Expand Down Expand Up @@ -804,13 +840,12 @@ bool QgsPostgresProvider::loadFields()
int attnum = result.PQftablecol( i );
int atttypid = attTypeIdMap[tableoid][attnum];

const QgsPostgresConn::PGTypeInfo &typeInfo = connectionRO()->type( fldtyp );
const PGTypeInfo &typeInfo = typeMap.value( fldtyp );
QString fieldTypeName = typeInfo.typeName;
QString fieldTType = typeInfo.typeType;
int fieldSize = typeInfo.typeLen;

const QgsPostgresConn::PGTypeInfo &attTypeInfo = connectionRO()->type( atttypid );
bool isDomain = ( attTypeInfo.typeType == QLatin1String( "d" ) );
bool isDomain = ( typeMap.value( atttypid ).typeType == QLatin1String( "d" ) );

QString formattedFieldType = fmtFieldTypeMap[tableoid][attnum];
QString originalFormattedFieldType = formattedFieldType;
Expand Down Expand Up @@ -1757,8 +1792,7 @@ bool QgsPostgresProvider::parseDomainCheckConstraint( QStringList &enumValues, c
enumValues.clear();

//is it a domain type with a check constraint?
QString domainSql = QStringLiteral( "SELECT domain_name,domain_schema FROM information_schema.columns WHERE table_schema=%1 AND table_name=%2 AND column_name=%3" )
.arg( quotedValue( mSchemaName ), quotedValue( mTableName ), quotedValue( attributeName ) );
QString domainSql = QStringLiteral( "SELECT domain_name, domain_schema FROM information_schema.columns WHERE table_name=%1 AND column_name=%2" ).arg( quotedValue( mTableName ), quotedValue( attributeName ) );
QgsPostgresResult domainResult( connectionRO()->PQexec( domainSql ) );
if ( domainResult.PQresultStatus() == PGRES_TUPLES_OK && domainResult.PQntuples() > 0 && !domainResult.PQgetvalue( 0, 0 ).isNull() )
{
Expand Down Expand Up @@ -3376,15 +3410,15 @@ bool QgsPostgresProvider::getGeometryDetails()
result = connectionRO()->PQexec( sql );
if ( tableoid > 0 && PGRES_TUPLES_OK == result.PQresultStatus() )
{
sql = QStringLiteral( "SELECT pg_namespace.nspname,pg_class.relname FROM pg_class JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid WHERE pg_class.oid=%1" ).arg( tableoid );
sql = QStringLiteral( "SELECT pg_namespace.nspname,pg_class.relname FROM pg_class,pg_namespace WHERE pg_class.relnamespace=pg_namespace.oid AND pg_class.oid=%1" ).arg( tableoid );
result = connectionRO()->PQexec( sql );

if ( PGRES_TUPLES_OK == result.PQresultStatus() && 1 == result.PQntuples() )
{
schemaName = result.PQgetvalue( 0, 0 );
tableName = result.PQgetvalue( 0, 1 );

sql = QStringLiteral( "SELECT a.attname, t.typname FROM pg_attribute a JOIN pg_type t ON a.atttypid = t.oid WHERE a.attrelid=%1 AND a.attnum=%2" ).arg( tableoid ).arg( column );
sql = QStringLiteral( "SELECT a.attname, t.typname FROM pg_attribute a, pg_type t WHERE a.attrelid=%1 AND a.attnum=%2 AND a.atttypid = t.oid" ).arg( tableoid ).arg( column );
result = connectionRO()->PQexec( sql );
if ( PGRES_TUPLES_OK == result.PQresultStatus() && 1 == result.PQntuples() )
{
Expand Down Expand Up @@ -3533,12 +3567,11 @@ bool QgsPostgresProvider::getGeometryDetails()

if ( mSpatialColType == SctNone )
{
sql = QString( "SELECT t.typname"
" FROM pg_attribute a"
" JOIN pg_class c ON a.attrelid=c.oid"
" JOIN pg_namespace n ON c.relnamespace=n.oid"
" JOIN pg_type t ON a.atttypid=t.oid"
" WHERE n.nspname=%3 AND c.relname=%1 AND a.attname=%2" )
sql = QString( "SELECT t.typname FROM "
"pg_attribute a, pg_class c, pg_namespace n, pg_type t "
"WHERE a.attrelid=c.oid AND c.relnamespace=n.oid "
"AND a.atttypid=t.oid "
"AND n.nspname=%3 AND c.relname=%1 AND a.attname=%2" )
.arg( quotedValue( tableName ),
quotedValue( geomCol ),
quotedValue( schemaName ) );
Expand Down
6 changes: 3 additions & 3 deletions src/server/services/wms/qgswmsgetcapabilities.cpp
Expand Up @@ -1062,10 +1062,10 @@ namespace QgsWms
if ( l->type() == QgsMapLayerType::VectorLayer )
{
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( l );
if ( vl && ( project->trustLayerMetadata() || vl->featureCount() == 0 ) )
if ( vl && vl->featureCount() == 0 )
{
// if we trust the project or there's no feature, use the wms
// extent defined in the project...
// if there's no feature, use the wms extent defined in the
// project...
extent = QgsServerProjectUtils::wmsExtent( *project );
if ( extent.isNull() )
{
Expand Down

0 comments on commit bf13d09

Please sign in to comment.