From 4edf1eec315695ded613cb8e7f5195cd52f68ebf Mon Sep 17 00:00:00 2001 From: Sebastian Dietrich Date: Fri, 13 Nov 2015 00:25:40 +0100 Subject: [PATCH 1/4] Added PQfmod() to class QgsPostgresResult --- src/providers/postgres/qgspostgresconn.cpp | 6 ++++++ src/providers/postgres/qgspostgresconn.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/providers/postgres/qgspostgresconn.cpp b/src/providers/postgres/qgspostgresconn.cpp index 82a03f3e28b7..b5121569274e 100644 --- a/src/providers/postgres/qgspostgresconn.cpp +++ b/src/providers/postgres/qgspostgresconn.cpp @@ -124,6 +124,12 @@ int QgsPostgresResult::PQftype( int col ) return ::PQftype( mRes, col ); } +int QgsPostgresResult::PQfmod( int col ) +{ + Q_ASSERT( mRes ); + return ::PQfmod( mRes, col ); +} + Oid QgsPostgresResult::PQoidValue() { Q_ASSERT( mRes ); diff --git a/src/providers/postgres/qgspostgresconn.h b/src/providers/postgres/qgspostgresconn.h index 6dffc4aea6f2..6de88348741c 100644 --- a/src/providers/postgres/qgspostgresconn.h +++ b/src/providers/postgres/qgspostgresconn.h @@ -167,6 +167,7 @@ class QgsPostgresResult QString PQfname( int col ); int PQftable( int col ); int PQftype( int col ); + int PQfmod( int col ); int PQftablecol( int col ); Oid PQoidValue(); From 6b3651faef3e02f48188ae8005c80b3a4e097a6b Mon Sep 17 00:00:00 2001 From: Sebastian Dietrich Date: Sat, 14 Nov 2015 13:18:56 +0100 Subject: [PATCH 2/4] Determine geometry type and srid directly from column type --- .../postgres/qgspostgresprovider.cpp | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/providers/postgres/qgspostgresprovider.cpp b/src/providers/postgres/qgspostgresprovider.cpp index 5ae27ba59cd2..c2d219cccef5 100644 --- a/src/providers/postgres/qgspostgresprovider.cpp +++ b/src/providers/postgres/qgspostgresprovider.cpp @@ -2910,7 +2910,42 @@ bool QgsPostgresProvider::getGeometryDetails() } else { - detectedType = mRequestedGeomType == QGis::WKBUnknown ? "" : QgsPostgresConn::postgisWkbTypeName( mRequestedGeomType ); + sql = QString( "SELECT %1 FROM %2 LIMIT 0" ).arg( quotedIdentifier( mGeometryColumn ), mQuery ); + result = connectionRO()->PQexec( sql ); + if ( PGRES_TUPLES_OK == result.PQresultStatus() ) + { + sql = QString( "SELECT (SELECT t.typname FROM pg_type t WHERE oid = %1), upper(postgis_typmod_type(%2)), postgis_typmod_srid(%2)" ) + .arg(QString::number( result.PQftype( 0 ) ), QString::number( result.PQfmod( 0 ) ) ); + result = connectionRO()->PQexec( sql ); + if ( result.PQntuples() == 1 ) + { + geomColType = result.PQgetvalue( 0, 0 ); + detectedType = result.PQgetvalue( 0, 1 ); + detectedSrid = result.PQgetvalue( 0, 2 ); + if ( geomColType == "geometry" ) + mSpatialColType = sctGeometry; + else if ( geomColType == "geography" ) + mSpatialColType = sctGeography; + else if ( geomColType == "topogeometry" ) + mSpatialColType = sctTopoGeometry; + else if ( geomColType == "pcpatch" ) + mSpatialColType = sctPcPatch; + else { + detectedType = mRequestedGeomType == QGis::WKBUnknown ? "" : QgsPostgresConn::postgisWkbTypeName( mRequestedGeomType ); + detectedSrid = mRequestedSrid; + } + } + else + { + connectionRO()->PQexecNR( "COMMIT" ); + detectedType = mRequestedGeomType == QGis::WKBUnknown ? "" : QgsPostgresConn::postgisWkbTypeName( mRequestedGeomType ); + } + } + else + { + mValid = false; + return false; + } } mDetectedGeomType = QgsPostgresConn::wkbTypeFromPostgis( detectedType ); From d9bbce65dacea8c09ced375bf35d6bb7711229a1 Mon Sep 17 00:00:00 2001 From: Sebastian Dietrich Date: Sun, 15 Nov 2015 13:42:07 +0100 Subject: [PATCH 3/4] Fix style and indentation isssues introduced in 6b3651faef3e02f48188ae8005c80b3a4e097a6b --- src/providers/postgres/qgspostgresprovider.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/providers/postgres/qgspostgresprovider.cpp b/src/providers/postgres/qgspostgresprovider.cpp index c2d219cccef5..d59446e75452 100644 --- a/src/providers/postgres/qgspostgresprovider.cpp +++ b/src/providers/postgres/qgspostgresprovider.cpp @@ -2915,7 +2915,7 @@ bool QgsPostgresProvider::getGeometryDetails() if ( PGRES_TUPLES_OK == result.PQresultStatus() ) { sql = QString( "SELECT (SELECT t.typname FROM pg_type t WHERE oid = %1), upper(postgis_typmod_type(%2)), postgis_typmod_srid(%2)" ) - .arg(QString::number( result.PQftype( 0 ) ), QString::number( result.PQfmod( 0 ) ) ); + .arg( QString::number( result.PQftype( 0 ) ), QString::number( result.PQfmod( 0 ) ) ); result = connectionRO()->PQexec( sql ); if ( result.PQntuples() == 1 ) { @@ -2930,7 +2930,8 @@ bool QgsPostgresProvider::getGeometryDetails() mSpatialColType = sctTopoGeometry; else if ( geomColType == "pcpatch" ) mSpatialColType = sctPcPatch; - else { + else + { detectedType = mRequestedGeomType == QGis::WKBUnknown ? "" : QgsPostgresConn::postgisWkbTypeName( mRequestedGeomType ); detectedSrid = mRequestedSrid; } From cfa308d5ac956cff3c13603c51605092bba56da5 Mon Sep 17 00:00:00 2001 From: Sebastian Dietrich Date: Sun, 15 Nov 2015 21:31:18 +0100 Subject: [PATCH 4/4] Added a test for the direct determination of geometry type/srid --- tests/src/python/test_provider_postgres.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/src/python/test_provider_postgres.py b/tests/src/python/test_provider_postgres.py index 867810e1fbc7..bf83a68a8b94 100644 --- a/tests/src/python/test_provider_postgres.py +++ b/tests/src/python/test_provider_postgres.py @@ -59,6 +59,14 @@ def testDefaultValue(self): assert self.provider.defaultValue(1) == NULL assert self.provider.defaultValue(2) == '\'qgis\'::text' + def testQueryLayers(self): + def test_query(dbconn, query, key): + ql = QgsVectorLayer('%s srid=4326 table="%s" (geom) key=\'%s\' sql=' % (dbconn, query.replace('"', '\\"'), key), "testgeom", "postgres") + print query, key + assert(ql.isValid()) + + test_query(self.dbconn, '(SELECT NULL::integer "Id1", NULL::integer "Id2", NULL::geometry(Point, 4326) geom LIMIT 0)', '"Id1","Id2"') + def testWkbTypes(self): def test_table(dbconn, table_name, wkt): vl = QgsVectorLayer('%s srid=4326 table="qgis_test".%s (geom) sql=' % (dbconn, table_name), "testgeom", "postgres")