Skip to content
Permalink
Browse files
Postgres: add ZM to type identification logic
Fixes #43268
  • Loading branch information
elpaso committed May 21, 2021
1 parent 59a6217 commit 4a386db413dc23adc9887321da3c86b1871c78b4
@@ -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,27 @@ void QgsPostgresConn::retrieveLayerTypes( QVector<QgsPostgresLayerProperty *> &l
if ( sridAndTypeString == "NULL" )
continue;

QStringList sridAndType = sridAndTypeString.split( ':' );
int srid = sridAndType[0].toInt();
const QStringList sridAndType = sridAndTypeString.split( ':' );
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 );
@@ -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 4a386db

Please sign in to comment.