Skip to content

Commit da21193

Browse files
committed
[mssql] Fix handling of geometry column when multiple geometry/geography
columns are present Fixes #13932
1 parent 71c5051 commit da21193

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

src/providers/mssql/qgsmssqlprovider.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,15 @@ void QgsMssqlProvider::loadFields()
338338
QStringList pkCandidates;
339339
while ( query.next() )
340340
{
341-
QString sqlTypeName = query.value( 5 ).toString();
342-
if ( sqlTypeName == QLatin1String( "geometry" ) || sqlTypeName == QLatin1String( "geography" ) )
341+
const QString colName = query.value( 3 ).toString();
342+
const QString sqlTypeName = query.value( 5 ).toString();
343+
344+
// if we don't have an explicitly set geometry column name, and this is a geometry column, then use it
345+
// but if we DO have an explicitly set geometry column name, then load the other information if this is that column
346+
if ( ( mGeometryColName.isEmpty() && ( sqlTypeName == QLatin1String( "geometry" ) || sqlTypeName == QLatin1String( "geography" ) ) )
347+
|| colName == mGeometryColName )
343348
{
344-
mGeometryColName = query.value( 3 ).toString();
349+
mGeometryColName = colName;
345350
mGeometryColType = sqlTypeName;
346351
mParser.IsGeography = sqlTypeName == QLatin1String( "geography" );
347352
}
@@ -350,7 +355,7 @@ void QgsMssqlProvider::loadFields()
350355
QVariant::Type sqlType = DecodeSqlType( sqlTypeName );
351356
if ( sqlTypeName == QLatin1String( "int identity" ) || sqlTypeName == QLatin1String( "bigint identity" ) )
352357
{
353-
mFidColName = query.value( 3 ).toString();
358+
mFidColName = colName;
354359
isIdentity = true;
355360
}
356361
else if ( sqlTypeName == QLatin1String( "int" ) || sqlTypeName == QLatin1String( "bigint" ) )
@@ -368,15 +373,15 @@ void QgsMssqlProvider::loadFields()
368373
}
369374
mAttributeFields.append(
370375
QgsField(
371-
query.value( 3 ).toString(), sqlType,
376+
colName, sqlType,
372377
sqlTypeName,
373378
length ) );
374379
}
375380
else if ( sqlType == QVariant::Double )
376381
{
377382
mAttributeFields.append(
378383
QgsField(
379-
query.value( 3 ).toString(), sqlType,
384+
colName, sqlType,
380385
sqlTypeName,
381386
query.value( 6 ).toInt(),
382387
sqlTypeName == QLatin1String( "decimal" ) ? query.value( 8 ).toInt() : -1 ) );
@@ -385,7 +390,7 @@ void QgsMssqlProvider::loadFields()
385390
{
386391
mAttributeFields.append(
387392
QgsField(
388-
query.value( 3 ).toString(), sqlType,
393+
colName, sqlType,
389394
sqlTypeName,
390395
-1,
391396
-1 ) );
@@ -394,7 +399,7 @@ void QgsMssqlProvider::loadFields()
394399
{
395400
mAttributeFields.append(
396401
QgsField(
397-
query.value( 3 ).toString(), sqlType,
402+
colName, sqlType,
398403
sqlTypeName ) );
399404
}
400405

tests/src/python/test_provider_mssql.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,21 @@ def testInsertPolygonInMultiPolygon(self):
298298
geom = [f.geometry().asWkt() for f in new_layer.getFeatures()]
299299
self.assertEqual(geom, ['MultiPolygon (((0 0, 1 0, 1 1, 0 1, 0 0)),((10 0, 11 0, 11 1, 10 1, 10 0)))', 'MultiPolygon (((30 0, 31 0, 31 1, 30 1, 30 0)))'])
300300

301+
def testMultiGeomColumns(self):
302+
uri = '{} table="qgis_test"."multiGeomColumns" (geom1) sql='.format(self.dbconn)
303+
new_layer = QgsVectorLayer(uri, 'new', 'mssql')
304+
self.assertTrue(new_layer.isValid())
305+
306+
geom = {f[0]: f.geometry().asWkt() for f in new_layer.getFeatures()}
307+
self.assertEqual(geom, {1: 'Point (2 3)', 2: 'Point (3 4)', 3: '', 4: 'Point (5 6)', 5: 'Point (1 2)'})
308+
309+
uri = '{} table="qgis_test"."multiGeomColumns" (geom2) sql='.format(self.dbconn)
310+
new_layer2 = QgsVectorLayer(uri, 'new', 'mssql')
311+
self.assertTrue(new_layer2.isValid())
312+
313+
geom = {f[0]: f.geometry().asWkt() for f in new_layer2.getFeatures()}
314+
self.assertEqual(geom, {1: 'LineString (2 3, 4 5)', 2: 'LineString (3 4, 5 6)', 3: 'LineString (1 2, 3 4)', 4: 'LineString (5 6, 7 8)', 5: ''})
315+
301316
def testInvalidGeometries(self):
302317
""" Test what happens when SQL Server is a POS and throws an exception on encountering an invalid geometry """
303318
vl = QgsVectorLayer('%s srid=4167 type=POLYGON table="qgis_test"."invalid_polys" (ogr_geometry) sql=' %

tests/testdata/provider/testdata_mssql.sql

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ GO
2222
DROP TABLE IF EXISTS qgis_test.[float_dec];
2323
GO
2424

25+
DROP TABLE IF EXISTS qgis_test.[multiGeomColumns];
26+
GO
27+
2528
DROP SCHEMA qgis_test;
2629
GO
2730

@@ -59,6 +62,13 @@ CREATE TABLE qgis_test.[float_dec] (
5962
);
6063
GO
6164

65+
CREATE TABLE qgis_test.[multiGeomColumns] (
66+
pk integer PRIMARY KEY,
67+
geom1 geometry,
68+
geom2 geometry
69+
);
70+
GO
71+
6272
INSERT INTO qgis_test.[someData] (pk, cnt, name, name2, num_char, geom) VALUES
6373
(5, -200, NULL, 'NuLl', '5', geometry::STGeomFromText( 'Point(-71.123 78.23)', 4326 )),
6474
(3, 300, 'Pear', 'PEaR', '3', NULL),
@@ -83,7 +93,14 @@ INSERT INTO qgis_test.[float_dec] (id, float_field, dec_field ) VALUES
8393
(1, 1.1111111111, 1.123 );
8494
GO
8595

86-
96+
INSERT INTO qgis_test.[multiGeomColumns] (pk, geom1, geom2) VALUES
97+
(5, geometry::STGeomFromText( 'Point( 1 2 )', 4326 ), NULL),
98+
(3, NULL, geometry::STGeomFromText( 'LineString( 1 2, 3 4 )', 4326 )),
99+
(1, geometry::STGeomFromText( 'Point( 2 3 )', 4326 ), geometry::STGeomFromText( 'LineString( 2 3, 4 5 )', 4326 )),
100+
(2, geometry::STGeomFromText( 'Point( 3 4 )', 4326 ), geometry::STGeomFromText( 'LineString( 3 4, 5 6 )', 4326 )),
101+
(4, geometry::STGeomFromText( 'Point( 5 6 )', 4326 ), geometry::STGeomFromText( 'LineString( 5 6, 7 8 )', 4326 ))
102+
;
103+
GO
87104

88105
/** Contains invalid polygons **/
89106
SET ANSI_NULLS ON

0 commit comments

Comments
 (0)