Skip to content
Permalink
Browse files
Merge pull request #43326 from elpaso/bugfix-gh43268-postgres-zm
Postgres: add ZM to type identification logic
  • Loading branch information
elpaso committed May 27, 2021
2 parents 10c69b3 + 130aa80 commit 0b511cc88126caae4aae193024aa81701b60d06d
@@ -61,10 +61,25 @@ QWidget *QgsPgSourceSelectDelegate::createEditor( QWidget *parent, const QStyleO
QComboBox *cb = new QComboBox( parent );
static const QList<QgsWkbTypes::Type> types { QgsWkbTypes::Point,
QgsWkbTypes::LineString,
QgsWkbTypes::LineStringZ,
QgsWkbTypes::LineStringM,
QgsWkbTypes::LineStringZM,
QgsWkbTypes::Polygon,
QgsWkbTypes::PolygonZ,
QgsWkbTypes::PolygonM,
QgsWkbTypes::PolygonZM,
QgsWkbTypes::MultiPoint,
QgsWkbTypes::MultiPointZ,
QgsWkbTypes::MultiPointM,
QgsWkbTypes::MultiPointZM,
QgsWkbTypes::MultiLineString,
QgsWkbTypes::MultiLineStringZ,
QgsWkbTypes::MultiLineStringM,
QgsWkbTypes::MultiLineStringZM,
QgsWkbTypes::MultiPolygon,
QgsWkbTypes::MultiPolygonZ,
QgsWkbTypes::MultiPolygonM,
QgsWkbTypes::MultiPolygonZM,
QgsWkbTypes::NoGeometry };
for ( QgsWkbTypes::Type type : types )
{
@@ -1900,7 +1900,7 @@ void QgsPostgresConn::retrieveLayerTypes( QVector<QgsPostgresLayerProperty *> &l
// SRID is already known
if ( srid != std::numeric_limits<int>::min() )
{
sql += QStringLiteral( "SELECT %1, array_agg( '%2:RASTER'::text )" )
sql += QStringLiteral( "SELECT %1, array_agg( '%2:RASTER:-1'::text )" )
.arg( i - 1 )
.arg( srid );
}
@@ -1909,7 +1909,7 @@ void QgsPostgresConn::retrieveLayerTypes( QVector<QgsPostgresLayerProperty *> &l
if ( useEstimatedMetadata )
{
sql = QStringLiteral( "SELECT %1, "
"array_agg( srid || ':RASTER') "
"array_agg( srid || ':RASTER:-1') "
"FROM raster_columns "
"WHERE r_raster_column = %2 AND r_table_schema = %3 AND r_table_name = %4" )
.arg( i - 1 )
@@ -1920,7 +1920,7 @@ void QgsPostgresConn::retrieveLayerTypes( QVector<QgsPostgresLayerProperty *> &l
else
{
sql = QStringLiteral( "SELECT %1, "
"array_agg( DISTINCT ST_SRID( %2 ) || ':RASTER' ) "
"array_agg( DISTINCT ST_SRID( %2 ) || ':RASTER:-1' ) "
"FROM %3 "
"%2 IS NOT NULL "
"%4 " // SQL clause
@@ -1983,13 +1983,13 @@ void QgsPostgresConn::retrieveLayerTypes( QVector<QgsPostgresLayerProperty *> &l
// full table. However SQL does not allow that.
// So we have to do a subselect on the table to add the LIMIT,
// see comment in the following code.
sql += QStringLiteral( "UPPER(geometrytype(%1%2))" )
sql += QStringLiteral( "UPPER(geometrytype(%1%2)) || ':' || ST_Zmflag(%1%2)" )
.arg( quotedIdentifier( layerProperty.geometryColName ),
castToGeometry ? "::geometry" : "" );
}
else
{
sql += QStringLiteral( "%1::text" )
sql += QStringLiteral( "%1::text || ':-1'" )
.arg( quotedValue( QgsPostgresConn::postgisWkbTypeName( type ) ) );
}

@@ -2061,9 +2061,28 @@ void QgsPostgresConn::retrieveLayerTypes( QVector<QgsPostgresLayerProperty *> &l
if ( sridAndTypeString == "NULL" )
continue;

QStringList sridAndType = sridAndTypeString.split( ':' );
int srid = sridAndType[0].toInt();
const QStringList sridAndType = sridAndTypeString.split( ':' );
Q_ASSERT( sridAndType.size() == 3 );
const int srid = sridAndType[0].toInt();
QString typeString = sridAndType[1];
const int zmFlags = sridAndType[2].toInt();

switch ( zmFlags )
{
case 1:
typeString.append( 'M' );
break;
case 2:
typeString.append( 'Z' );
break;
case 3:
typeString.append( QStringLiteral( "ZM" ) );
break;
default:
case 0:
case -1:
break;
}

auto type = QgsPostgresConn::wkbTypeFromPostgis( typeString );
auto flatType = QgsWkbTypes::flatType( type );
@@ -2332,10 +2351,34 @@ QgsWkbTypes::Type QgsPostgresConn::wkbTypeFromPostgis( const QString &type )
{
return QgsWkbTypes::MultiPolygon;
}
else if ( ( type == QLatin1String( "POLYHEDRALSURFACEZ" ) ) || ( type == QLatin1String( "TINZ" ) ) )
{
return QgsWkbTypes::MultiPolygonZ;
}
else if ( ( type == QLatin1String( "POLYHEDRALSURFACEM" ) ) || ( type == QLatin1String( "TINM" ) ) )
{
return QgsWkbTypes::MultiPolygonM;
}
else if ( ( type == QLatin1String( "POLYHEDRALSURFACEZM" ) ) || ( type == QLatin1String( "TINZM" ) ) )
{
return QgsWkbTypes::MultiPolygonZM;
}
else if ( type == QLatin1String( "TRIANGLE" ) )
{
return QgsWkbTypes::Polygon;
}
else if ( type == QLatin1String( "TRIANGLEZ" ) )
{
return QgsWkbTypes::PolygonZ;
}
else if ( type == QLatin1String( "TRIANGLEM" ) )
{
return QgsWkbTypes::PolygonM;
}
else if ( type == QLatin1String( "TRIANGLEZM" ) )
{
return QgsWkbTypes::PolygonZM;
}
return QgsWkbTypes::parseType( type );
}

@@ -377,6 +377,24 @@ def test_exceptions(self):
with self.assertRaises(QgsProviderConnectionException):
conn.table('my_not_existent_schema', 'my_not_existent_table')

def test_zm(self):
"""Test regression GH #43268"""

md = QgsProviderRegistry.instance().providerMetadata('postgres')
conn = md.createConnection(self.uri, {})
sql = """
DROP TABLE IF EXISTS qgis_test.gh_43268_test_zm;
CREATE TABLE qgis_test.gh_43268_test_zm (geom geometry(GeometryZ));
INSERT INTO qgis_test.gh_43268_test_zm (geom) VALUES
('POINT(0 0 0)'),
('LINESTRING(0 0 0, 0 0 0)'),
('POLYGON((0 0 0, 0 0 0, 0 0 0, 0 0 0))');
"""
conn.executeSql(sql)

table_info = conn.table('qgis_test', 'gh_43268_test_zm')
self.assertEqual(sorted([QgsWkbTypes.displayString(col.wkbType) for col in table_info.geometryColumnTypes()]), ['LineStringZ', 'PointZ', 'PolygonZ'])


if __name__ == '__main__':
unittest.main()

0 comments on commit 0b511cc

Please sign in to comment.