[QGIS Commit] r13221 - trunk/qgis/src/providers/postgres

svn_qgis at osgeo.org svn_qgis at osgeo.org
Thu Apr 1 08:58:05 EDT 2010


Author: jef
Date: 2010-04-01 08:58:04 -0400 (Thu, 01 Apr 2010)
New Revision: 13221

Modified:
   trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
   trunk/qgis/src/providers/postgres/qgspostgresprovider.h
Log:
use other approach to avoid estimate_extents on not analyzed tables

Modified: trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
===================================================================
--- trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp	2010-04-01 12:53:58 UTC (rev 13220)
+++ trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp	2010-04-01 12:58:04 UTC (rev 13221)
@@ -234,28 +234,6 @@
 
   // Kick off the long running threads
 
-#ifdef POSTGRESQL_THREADS
-  QgsDebugMsg( "About to touch mExtentThread" );
-  mExtentThread.setConnInfo( mUri.connectionInfo );
-  mExtentThread.setTableName( mTableName );
-  mExtentThread.setSqlWhereClause( sqlWhereClause );
-  mExtentThread.setGeometryColumn( geometryColumn );
-  mExtentThread.setCallback( this );
-  QgsDebugMsg( "About to start mExtentThread" );
-  mExtentThread.start();
-  QgsDebugMsg( "Main thread just dispatched mExtentThread" );
-
-  QgsDebugMsg( "About to touch mCountThread" );
-  mCountThread.setConnInfo( mUri.connectionInfo );
-  mCountThread.setTableName( mTableName );
-  mCountThread.setSqlWhereClause( sqlWhereClause );
-  mCountThread.setGeometryColumn( geometryColumn );
-  mCountThread.setCallback( this );
-  QgsDebugMsg( "About to start mCountThread" );
-  mCountThread.start();
-  QgsDebugMsg( "Main thread just dispatched mCountThread" );
-#endif
-
   //fill type names into sets
   mNativeTypes
   // integer types
@@ -292,25 +270,6 @@
 
 QgsPostgresProvider::~QgsPostgresProvider()
 {
-#ifdef POSTGRESQL_THREADS
-  QgsDebugMsg( "About to wait for mExtentThread" );
-
-  mExtentThread.wait();
-
-  QgsDebugMsg( "Finished waiting for mExtentThread" );
-
-  QgsDebugMsg( "About to wait for mCountThread" );
-
-  mCountThread.wait();
-
-  QgsDebugMsg( "Finished waiting for mCountThread" );
-
-  // Make sure all events from threads have been processed
-  // (otherwise they will get destroyed prematurely)
-  QApplication::sendPostedEvents( this, QGis::ProviderExtentCalcEvent );
-  QApplication::sendPostedEvents( this, QGis::ProviderCountCalcEvent );
-#endif
-
   disconnectDb();
 
   QgsDebugMsg( "deconstructing." );
@@ -2730,68 +2689,38 @@
   return featuresCounted;
 }
 
-// TODO: use the estimateExtents procedure of PostGIS and PostgreSQL 8
-// This tip thanks to #qgis irc nick "creeping"
 void QgsPostgresProvider::calculateExtents()
 {
-#ifdef POSTGRESQL_THREADS
-  // get the approximate extent by retrieving the bounding box
-  // of the first few items with a geometry
-
-  QString sql = QString( "select box3d(%1) from %2 where " )
-                .arg( quotedIdentifier( geometryColumn ) )
-                .arg( mSchemaTableName );
-
-  if ( sqlWhereClause.length() > 0 )
-  {
-    sql += QString( "(%1) and " ).arg( sqlWhereClause );
-  }
-
-  sql += QString( "not IsEmpty(%1) limit 5" ).arg( quotedIdentifier( geometryColumn ) );
-
-  QgsDebugMsg( "Getting approximate extent using: '" + sql + "'" );
-
-  Result result = connectionRO->PQexec( sql );
-
-  // TODO: Guard against the result having no rows
-  for ( int i = 0; i < PQntuples( result ); i++ )
-  {
-    QString box3d = PQgetvalue( result, i, 0 );
-
-    if ( 0 == i )
-    {
-      // create the initial extent
-      layerExtent = QgsPostGisBox3d( box3d );
-    }
-    else
-    {
-      // extend the initial extent
-      QgsPostGisBox3d b = QgsPostGisBox3d( box3d );
-      layerExtent.combineExtentWith( &b );
-    }
-
-    QgsDebugMsg( QString( "After row %1, extent is %2" ).arg( i ).arg( layerExtent.toString() ) );
-  }
-
-#else // non-postgresql threads version
   QString sql;
   Result result;
   QString ext;
 
   // get the extents
-  if (( mUseEstimatedMetadata || sqlWhereClause.isEmpty() ) && !connectionRO->hasNoExtentEstimate() )
+  if ( mUseEstimatedMetadata || sqlWhereClause.isEmpty() )
   {
-    result = connectionRO->PQexec( QString( "select estimated_extent(%1,%2,%3)" )
-                                   .arg( quotedValue( mSchemaName ) )
-                                   .arg( quotedValue( mTableName ) )
-                                   .arg( quotedValue( geometryColumn ) ) );
-    if ( PQresultStatus( result ) != PGRES_TUPLES_OK )
+    // do stats exists?
+    sql = QString( "SELECT COUNT(*) FROM pg_stats WHERE schemaname=%1 AND tablename=%2 AND attname=%3" )
+          .arg( quotedValue( mSchemaName ) )
+          .arg( quotedValue( mTableName ) )
+          .arg( quotedValue( geometryColumn ) );
+    result = connectionRO->PQexec( sql );
+    if ( PQresultStatus( result ) == PGRES_TUPLES_OK && PQntuples( result ) == 1 )
     {
-      connectionRO->PQexecNR( "ROLLBACK" );
-      connectionRO->setNoExtentEstimate();
+      if ( QString::fromUtf8( PQgetvalue( result, 0, 0 ) ).toInt() > 0 )
+      {
+        sql = QString( "select estimated_extent(%1,%2,%3)" )
+              .arg( quotedValue( mSchemaName ) )
+              .arg( quotedValue( mTableName ) )
+              .arg( quotedValue( geometryColumn ) );
+        result = connectionRO->PQexec( sql );
+        if ( PQresultStatus( result ) == PGRES_TUPLES_OK && PQntuples( result ) == 1 )
+          ext = PQgetvalue( result, 0, 0 );
+      }
     }
-    else if ( PQntuples( result ) == 1 )
-      ext = PQgetvalue( result, 0, 0 );
+    else
+    {
+      QgsDebugMsg( QString( "no column statistics for %1.%2.%3" ).arg( mSchemaName ).arg( mTableName ).arg( geometryColumn ) );
+    }
   }
 
   if ( ext.isEmpty() )
@@ -2810,7 +2739,7 @@
       ext = PQgetvalue( result, 0, 0 );
   }
 
-  QgsDebugMsg( "Getting extents using schema.table: " + sql );
+  QgsDebugMsg( "Got extents using: " + sql );
 
   QRegExp rx( "\\((.+) (.+),(.+) (.+)\\)" );
   if ( ext.contains( rx ) )
@@ -2826,7 +2755,6 @@
   {
     QgsDebugMsg( "extents query failed" );
   }
-#endif
 
   QgsDebugMsg( "Set extents to: " + layerExtent.toString() );
 }

Modified: trunk/qgis/src/providers/postgres/qgspostgresprovider.h
===================================================================
--- trunk/qgis/src/providers/postgres/qgspostgresprovider.h	2010-04-01 12:53:58 UTC (rev 13220)
+++ trunk/qgis/src/providers/postgres/qgspostgresprovider.h	2010-04-01 12:58:04 UTC (rev 13221)
@@ -584,12 +584,11 @@
     class Conn
     {
       public:
-        Conn( PGconn *connection ) :
-            ref( 1 ),
-            openCursors( 0 ),
-            conn( connection ),
-            gotPostgisVersion( false ),
-            mHasNoExtentEstimate( false )
+        Conn( PGconn *connection )
+            : ref( 1 )
+            , openCursors( 0 )
+            , conn( connection )
+            , gotPostgisVersion( false )
         {
         }
 
@@ -614,12 +613,6 @@
         //! 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 );
 
@@ -678,9 +671,6 @@
         //! encode wkb in hex
         bool mUseWkbHex;
 
-        //! PostGIS doesn't have extent estimates
-        bool mHasNoExtentEstimate;
-
         static QMap<QString, Conn *> connectionsRW;
         static QMap<QString, Conn *> connectionsRO;
         static QMap<QString, QString> passwordCache;



More information about the QGIS-commit mailing list