From b0a9d99453e3523acc7a8e1e64a48eae4ebc1229 Mon Sep 17 00:00:00 2001 From: jef Date: Sun, 7 Mar 2010 17:34:20 +0000 Subject: [PATCH] fix #2511 git-svn-id: http://svn.osgeo.org/qgis/trunk@13014 c8812cc2-4d05-0410-92ff-de0c093fc19c --- .../postgres/qgspostgresprovider.cpp | 82 +++++++++---------- src/providers/postgres/qgspostgresprovider.h | 22 ++++- 2 files changed, 59 insertions(+), 45 deletions(-) diff --git a/src/providers/postgres/qgspostgresprovider.cpp b/src/providers/postgres/qgspostgresprovider.cpp index e9ff381216a7..2b60dd7c9df1 100644 --- a/src/providers/postgres/qgspostgresprovider.cpp +++ b/src/providers/postgres/qgspostgresprovider.cpp @@ -115,12 +115,26 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri ) return; } - sql = QString( "SELECT " - "has_table_privilege(%1,'DELETE')," - "has_table_privilege(%1,'UPDATE')," - "has_table_privilege(%1,'INSERT')," - "current_schema()" ) - .arg( quotedValue( mSchemaTableName ) ); + if ( connectionRO->pgVersion() >= 80400 ) + { + sql = QString( "SELECT " + "has_table_privilege(%1,'DELETE')," + "has_any_column_privilege(%1,'UPDATE')," + "has_column_privilege(%1,%2,'UPDATE')," + "has_table_privilege(%1,'INSERT')," + "current_schema()" ) + .arg( quotedValue( mSchemaTableName ) ).arg( quotedValue( geometryColumn ) ); + } + else + { + sql = QString( "SELECT " + "has_table_privilege(%1,'DELETE')," + "has_table_privilege(%1,'UPDATE')," + "has_table_privilege(%1,'UPDATE')," + "has_table_privilege(%1,'INSERT')," + "current_schema()" ) + .arg( quotedValue( mSchemaTableName ) ); + } testAccess = connectionRO->PQexec( sql ); if ( PQresultStatus( testAccess ) != PGRES_TUPLES_OK ) @@ -148,16 +162,22 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri ) if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 1 ) ) == "t" ) { // UPDATE - enabledCapabilities |= QgsVectorDataProvider::ChangeGeometries | QgsVectorDataProvider::ChangeAttributeValues; + enabledCapabilities |= QgsVectorDataProvider::ChangeAttributeValues; } if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 2 ) ) == "t" ) + { + // UPDATE + enabledCapabilities |= QgsVectorDataProvider::ChangeGeometries; + } + + if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 3 ) ) == "t" ) { // INSERT enabledCapabilities |= QgsVectorDataProvider::AddFeatures; } - mCurrentSchema = QString::fromUtf8( PQgetvalue( testAccess, 0, 3 ) ); + mCurrentSchema = QString::fromUtf8( PQgetvalue( testAccess, 0, 4 ) ); if ( mCurrentSchema == mSchemaName ) { mUri.clearSchema(); @@ -2055,6 +2075,8 @@ bool QgsPostgresProvider::Conn::hasGEOS() /* Functions for determining available features in postGIS */ QString QgsPostgresProvider::Conn::postgisVersion() { + postgresqlVersion = PQserverVersion( conn ); + Result result = PQexec( "select postgis_version()" ); if ( PQntuples( result ) != 1 ) { @@ -2694,15 +2716,6 @@ void QgsPostgresProvider::calculateExtents() sql += QString( "not IsEmpty(%1) limit 5" ).arg( quotedIdentifier( geometryColumn ) ); -#if WASTE_TIME - sql = QString( "select " - "xmax(extent(%1)) as xmax," - "xmin(extent(%1)) as xmin," - "ymax(extent(%1)) as ymax," - "ymin(extent(%1)) as ymin" - " from %2" ).arg( quotedIdentifier( geometryColumn ) ).arg( mSchemaTableName ); -#endif - QgsDebugMsg( "Getting approximate extent using: '" + sql + "'" ); Result result = connectionRO->PQexec( sql ); @@ -2733,13 +2746,18 @@ void QgsPostgresProvider::calculateExtents() QString ext; // get the extents - if ( sqlWhereClause.isEmpty() ) + if ( sqlWhereClause.isEmpty() && !connectionRO->hasNoExtentEstimate() ) { result = connectionRO->PQexec( QString( "select estimated_extent(%1,%2,%3)" ) .arg( quotedValue( mSchemaName ) ) .arg( quotedValue( mTableName ) ) .arg( quotedValue( geometryColumn ) ) ); - if ( PQntuples( result ) == 1 ) + if ( PQresultStatus( result ) != PGRES_TUPLES_OK ) + { + connectionRO->PQexecNR( "ROLLBACK" ); + connectionRO->setNoExtentEstimate(); + } + else if ( PQntuples( result ) == 1 ) ext = PQgetvalue( result, 0, 0 ); } @@ -2753,19 +2771,12 @@ void QgsPostgresProvider::calculateExtents() sql += QString( "where %1" ).arg( sqlWhereClause ); result = connectionRO->PQexec( sql ); - if ( PQntuples( result ) == 1 ) + if ( PQresultStatus( result ) != PGRES_TUPLES_OK ) + connectionRO->PQexecNR( "ROLLBACK" ); + else if ( PQntuples( result ) == 1 ) ext = PQgetvalue( result, 0, 0 ); } -#if WASTE_TIME - sql = QString( "select " - "xmax(extent(%1)) as xmax," - "xmin(extent(%1)) as xmin," - "ymax(extent(%1)) as ymax," - "ymin(extent(%1)) as ymin" - " from %2" ).arg( quotedIdentifier( geometryColumn ) ).arg( mSchemaTableName ); -#endif - QgsDebugMsg( "Getting extents using schema.table: " + sql ); QRegExp rx( "\\((.+) (.+),(.+) (.+)\\)" ); @@ -2784,19 +2795,6 @@ void QgsPostgresProvider::calculateExtents() } #endif -#if 0 -#ifdef QGISDEBUG - QString xMsg; - QTextOStream( &xMsg ).precision( 18 ); - QTextOStream( &xMsg ).width( 18 ); - QTextOStream( &xMsg ) << "QgsPostgresProvider: Set extents to: " - << layerExtent.xMinimum() << ", " - << layerExtent.yMinimum() << " " - << layerExtent.xMaximum() << ", " - << layerExtent.yMaximum(); - QgsDebugMsg( xMsg ); -#endif -#endif QgsDebugMsg( "Set extents to: " + layerExtent.toString() ); } diff --git a/src/providers/postgres/qgspostgresprovider.h b/src/providers/postgres/qgspostgresprovider.h index 52c8a4b4ea30..8c1d377881c0 100644 --- a/src/providers/postgres/qgspostgresprovider.h +++ b/src/providers/postgres/qgspostgresprovider.h @@ -581,7 +581,8 @@ class QgsPostgresProvider : public QgsVectorDataProvider ref( 1 ), openCursors( 0 ), conn( connection ), - gotPostgisVersion( false ) + gotPostgisVersion( false ), + mHasNoExtentEstimate( false ) { } @@ -603,10 +604,19 @@ class QgsPostgresProvider : public QgsVectorDataProvider //! major PostgreSQL version int majorVersion() { return postgisVersionMajor; } - // run a query and free result buffer + //! PostgreSQL version + int pgVersion() { return postgresqlVersion; } + + //! has PostGIS no extent estimate? + bool hasNoExtentEstimate() { return mHasNoExtentEstimate; } + + //! PostGIS does not have a extent estimate + void setNoExtentEstimate( bool flag = true ) { mHasNoExtentEstimate = flag; } + + //! run a query and free result buffer bool PQexecNR( QString query ); - // cursor handling + //! cursor handling bool openCursor( QString cursorName, QString declare ); bool closeCursor( QString cursorName ); @@ -643,6 +653,9 @@ class QgsPostgresProvider : public QgsVectorDataProvider //! Are postgisVersionMajor, postgisVersionMinor, geosAvailable, gistAvailable, projAvailable valid? bool gotPostgisVersion; + //! PostgreSQL version + int postgresqlVersion; + //! PostGIS major version int postgisVersionMajor; @@ -658,6 +671,9 @@ class QgsPostgresProvider : public QgsVectorDataProvider //! encode wkb in hex bool mUseWkbHex; + //! PostGIS doesn't have extent estimates + bool mHasNoExtentEstimate; + static QMap connectionsRW; static QMap connectionsRO; static QMap passwordCache;