Skip to content

Commit dafeaf4

Browse files
committed
[mssql][needs-docs] Add connection setting to ignore invalid geometry handling
Sets whether the connection should skip all handling of records with invalid geometry, which are slow and costly. This speeds up the provider, however, if any invalid geometries are present in a table then the result is unpredictable and may include missing records. Only check this option if you are certain that all geometries present in the database are valid, and any newly added geometries or tables will also be valid! Why would we want this? Well, SQL Server invalid geometry handling is AWEFUL. A seriously lame, data mangling and corrupting piece of s***. Use Postgres instead. But if you can't, then you can at least choose to use your layers at full speed, if you can take the responsibility that a SINGLE invalid geometry hiding somewhere in the table will result in a whole bunch of missing (valid) features. SQL server is at fault here, not us. There's nothing we (or GDAL, or MapServer, or GeoServer, or anyone else) can do to fix this. Suffice to say, this option is off by default, as we're better to have a slow provider which actually shows all features. Fixes #15752 Rant over
1 parent 7464575 commit dafeaf4

13 files changed

+157
-36
lines changed

src/providers/mssql/qgsmssqlconnection.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,18 @@ void QgsMssqlConnection::setUseEstimatedMetadata( const QString &name, bool enab
142142
settings.setValue( "/MSSQL/connections/" + name + "/estimatedMetadata", enabled );
143143
}
144144

145+
bool QgsMssqlConnection::isInvalidGeometryHandlingDisabled( const QString &name )
146+
{
147+
QgsSettings settings;
148+
return settings.value( "/MSSQL/connections/" + name + "/disableInvalidGeometryHandling", false ).toBool();
149+
}
150+
151+
void QgsMssqlConnection::setInvalidGeometryHandlingDisabled( const QString &name, bool disabled )
152+
{
153+
QgsSettings settings;
154+
settings.setValue( "/MSSQL/connections/" + name + "/disableInvalidGeometryHandling", disabled );
155+
}
156+
145157
QString QgsMssqlConnection::dbConnectionName( const QString &name )
146158
{
147159
// Starting with Qt 5.11, sharing the same connection between threads is not allowed.

src/providers/mssql/qgsmssqlconnection.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,27 +61,63 @@ class QgsMssqlConnection
6161
/**
6262
* Returns true if the connection with matching \a name should
6363
* show geometryless tables when scanning for tables.
64+
*
65+
* \see setAllowGeometrylessTables()
6466
*/
6567
static bool allowGeometrylessTables( const QString &name );
6668

6769
/**
6870
* Sets whether the connection with matching \a name should
6971
* show geometryless tables when scanning for tables.
72+
*
73+
* \see allowGeometrylessTables()
7074
*/
7175
static void setAllowGeometrylessTables( const QString &name, bool enabled );
7276

7377
/**
7478
* Returns true if the connection with matching \a name should
7579
* use estimated table parameters.
80+
*
81+
* \see setUseEstimatedMetadata()
7682
*/
7783
static bool useEstimatedMetadata( const QString &name );
7884

7985
/**
8086
* Sets whether the connection with matching \a name should
8187
* use estimated table parameters.
88+
*
89+
* \see useEstimatedMetadata()
8290
*/
8391
static void setUseEstimatedMetadata( const QString &name, bool enabled );
8492

93+
/**
94+
* Returns true if the connection with matching \a name should
95+
* skip all handling of records with invalid geometry.
96+
*
97+
* This speeds up the provider, however, if any invalid geometries
98+
* are present in a table then the result is unpredictable and may
99+
* include missing records. Only check this option if you are certain
100+
* that all geometries present in the database are valid, and any newly
101+
* added geometries or tables will also be valid.
102+
*
103+
* \see setInvalidGeometryHandlingDisabled()
104+
*/
105+
static bool isInvalidGeometryHandlingDisabled( const QString &name );
106+
107+
/**
108+
* Sets whether the the connection with matching \a name should
109+
* skip all handling of records with invalid geometry.
110+
*
111+
* This speeds up the provider, however, if any invalid geometries
112+
* are present in a table then the result is unpredictable and may
113+
* include missing records. Only check this option if you are certain
114+
* that all geometries present in the database are valid, and any newly
115+
* added geometries or tables will also be valid.
116+
*
117+
* \see isInvalidGeometryHandlingDisabled()
118+
*/
119+
static void setInvalidGeometryHandlingDisabled( const QString &name, bool disabled );
120+
85121
private:
86122

87123
/**

src/providers/mssql/qgsmssqldataitems.cpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
#include <QProgressDialog>
4141

4242
// ---------------------------------------------------------------------------
43-
QgsMssqlConnectionItem::QgsMssqlConnectionItem( QgsDataItem *parent, QString name, QString path )
43+
QgsMssqlConnectionItem::QgsMssqlConnectionItem( QgsDataItem *parent, const QString &name, const QString &path )
4444
: QgsDataCollectionItem( parent, name, path )
4545
, mUseGeometryColumns( false )
4646
, mUseEstimatedMetadata( false )
@@ -109,7 +109,7 @@ void QgsMssqlConnectionItem::refresh()
109109
int index = findItem( mChildren, item );
110110
if ( index >= 0 )
111111
{
112-
( ( QgsMssqlSchemaItem * )mChildren.at( index ) )->addLayers( item );
112+
static_cast< QgsMssqlSchemaItem * >( mChildren.at( index ) )->addLayers( item );
113113
delete item;
114114
continue;
115115
}
@@ -154,6 +154,8 @@ QVector<QgsDataItem *> QgsMssqlConnectionItem::createChildren()
154154
query += QLatin1String( " union all select sys.schemas.name, sys.objects.name, null, null, 'NONE' from sys.objects join sys.schemas on sys.objects.schema_id = sys.schemas.schema_id where not exists (select * from sys.columns sc1 join sys.types on sc1.system_type_id = sys.types.system_type_id where (sys.types.name = 'geometry' or sys.types.name = 'geography') and sys.objects.object_id = sc1.object_id) and (sys.objects.type = 'U' or sys.objects.type = 'V')" );
155155
}
156156

157+
const bool disableInvalidGeometryHandling = QgsMssqlConnection::isInvalidGeometryHandlingDisabled( mName );
158+
157159
// issue the sql query
158160
QSqlQuery q = QSqlQuery( db );
159161
q.setForwardOnly( true );
@@ -181,7 +183,8 @@ QVector<QgsDataItem *> QgsMssqlConnectionItem::createChildren()
181183
{
182184
Q_FOREACH ( QgsDataItem *child2, child->children() )
183185
{
184-
if ( child2->name() == layer.tableName )
186+
QgsMssqlLayerItem *layerItem = qobject_cast< QgsMssqlLayerItem *>( child2 );
187+
if ( child2->name() == layer.tableName && layerItem && layerItem->disableInvalidGeometryHandling() == disableInvalidGeometryHandling )
185188
{
186189
newLayers.append( child2 );
187190
skip = true; // already added
@@ -202,7 +205,7 @@ QVector<QgsDataItem *> QgsMssqlConnectionItem::createChildren()
202205
{
203206
if ( child->name() == layer.schemaName )
204207
{
205-
schemaItem = ( QgsMssqlSchemaItem * )child;
208+
schemaItem = static_cast< QgsMssqlSchemaItem * >( child );
206209
break;
207210
}
208211
}
@@ -289,14 +292,14 @@ void QgsMssqlConnectionItem::setLayerType( QgsMssqlLayerProperty layerProperty )
289292
{
290293
if ( child->name() == layerProperty.schemaName )
291294
{
292-
schemaItem = ( QgsMssqlSchemaItem * )child;
295+
schemaItem = static_cast< QgsMssqlSchemaItem * >( child );
293296
break;
294297
}
295298
}
296299

297300
if ( !schemaItem )
298301
{
299-
QgsDebugMsg( QString( "schema item for %1 not found." ).arg( layerProperty.schemaName ) );
302+
QgsDebugMsg( QStringLiteral( "schema item for %1 not found." ).arg( layerProperty.schemaName ) );
300303
return;
301304
}
302305

@@ -315,7 +318,7 @@ void QgsMssqlConnectionItem::setLayerType( QgsMssqlLayerProperty layerProperty )
315318
QgsWkbTypes::Type wkbType = QgsMssqlTableModel::wkbTypeFromMssql( typeList[i] );
316319
if ( wkbType == QgsWkbTypes::Unknown )
317320
{
318-
QgsDebugMsg( QString( "unsupported geometry type:%1" ).arg( typeList[i] ) );
321+
QgsDebugMsg( QStringLiteral( "unsupported geometry type:%1" ).arg( typeList[i] ) );
319322
continue;
320323
}
321324

@@ -476,7 +479,7 @@ bool QgsMssqlConnectionItem::handleDrop( const QMimeData *data, const QString &t
476479

477480

478481
// ---------------------------------------------------------------------------
479-
QgsMssqlLayerItem::QgsMssqlLayerItem( QgsDataItem *parent, QString name, QString path, QgsLayerItem::LayerType layerType, QgsMssqlLayerProperty layerProperty )
482+
QgsMssqlLayerItem::QgsMssqlLayerItem( QgsDataItem *parent, const QString &name, const QString &path, QgsLayerItem::LayerType layerType, const QgsMssqlLayerProperty &layerProperty )
480483
: QgsLayerItem( parent, name, path, QString(), layerType, QStringLiteral( "mssql" ) )
481484
, mLayerProperty( layerProperty )
482485
{
@@ -489,27 +492,36 @@ QgsMssqlLayerItem *QgsMssqlLayerItem::createClone()
489492
return new QgsMssqlLayerItem( mParent, mName, mPath, mLayerType, mLayerProperty );
490493
}
491494

495+
bool QgsMssqlLayerItem::disableInvalidGeometryHandling() const
496+
{
497+
return mDisableInvalidGeometryHandling;
498+
}
499+
492500
QString QgsMssqlLayerItem::createUri()
493501
{
494502
QString pkColName = !mLayerProperty.pkCols.isEmpty() ? mLayerProperty.pkCols.at( 0 ) : QString();
495503
QgsMssqlConnectionItem *connItem = qobject_cast<QgsMssqlConnectionItem *>( parent() ? parent()->parent() : nullptr );
496504

497505
if ( !connItem )
498506
{
499-
QgsDebugMsg( "connection item not found." );
507+
QgsDebugMsg( QStringLiteral( "connection item not found." ) );
500508
return QString();
501509
}
502510

503511
QgsDataSourceUri uri = QgsDataSourceUri( connItem->connInfo() );
504512
uri.setDataSource( mLayerProperty.schemaName, mLayerProperty.tableName, mLayerProperty.geometryColName, mLayerProperty.sql, pkColName );
505513
uri.setSrid( mLayerProperty.srid );
506514
uri.setWkbType( QgsMssqlTableModel::wkbTypeFromMssql( mLayerProperty.type ) );
507-
QgsDebugMsg( QString( "layer uri: %1" ).arg( uri.uri() ) );
515+
uri.setUseEstimatedMetadata( QgsMssqlConnection::useEstimatedMetadata( connItem->name() ) );
516+
mDisableInvalidGeometryHandling = QgsMssqlConnection::isInvalidGeometryHandlingDisabled( connItem->name() );
517+
uri.setParam( QStringLiteral( "disableInvalidGeometryHandling" ), mDisableInvalidGeometryHandling ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
518+
519+
QgsDebugMsg( QStringLiteral( "layer uri: %1" ).arg( uri.uri() ) );
508520
return uri.uri();
509521
}
510522

511523
// ---------------------------------------------------------------------------
512-
QgsMssqlSchemaItem::QgsMssqlSchemaItem( QgsDataItem *parent, QString name, QString path )
524+
QgsMssqlSchemaItem::QgsMssqlSchemaItem( QgsDataItem *parent, const QString &name, const QString &path )
513525
: QgsDataCollectionItem( parent, name, path )
514526
{
515527
mIconName = QStringLiteral( "mIconDbSchema.svg" );
@@ -519,7 +531,6 @@ QgsMssqlSchemaItem::QgsMssqlSchemaItem( QgsDataItem *parent, QString name, QStri
519531

520532
QVector<QgsDataItem *> QgsMssqlSchemaItem::createChildren()
521533
{
522-
QgsDebugMsg( "Entering." );
523534
return QVector<QgsDataItem *>();
524535
}
525536

@@ -533,7 +544,7 @@ void QgsMssqlSchemaItem::addLayers( QgsDataItem *newLayers )
533544
{
534545
continue;
535546
}
536-
QgsMssqlLayerItem *layer = ( ( QgsMssqlLayerItem * )child )->createClone();
547+
QgsMssqlLayerItem *layer = static_cast< QgsMssqlLayerItem * >( child )->createClone();
537548
addChildItem( layer, true );
538549
}
539550
}
@@ -591,7 +602,7 @@ QgsMssqlLayerItem *QgsMssqlSchemaItem::addLayer( const QgsMssqlLayerProperty &la
591602
}
592603

593604
// ---------------------------------------------------------------------------
594-
QgsMssqlRootItem::QgsMssqlRootItem( QgsDataItem *parent, QString name, QString path )
605+
QgsMssqlRootItem::QgsMssqlRootItem( QgsDataItem *parent, const QString &name, const QString &path )
595606
: QgsDataCollectionItem( parent, name, path )
596607
{
597608
mIconName = QStringLiteral( "mIconMssql.svg" );

src/providers/mssql/qgsmssqldataitems.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class QgsMssqlRootItem : public QgsDataCollectionItem
3434
{
3535
Q_OBJECT
3636
public:
37-
QgsMssqlRootItem( QgsDataItem *parent, QString name, QString path );
37+
QgsMssqlRootItem( QgsDataItem *parent, const QString &name, const QString &path );
3838

3939
QVector<QgsDataItem *> createChildren() override;
4040

@@ -56,7 +56,7 @@ class QgsMssqlConnectionItem : public QgsDataCollectionItem
5656
{
5757
Q_OBJECT
5858
public:
59-
QgsMssqlConnectionItem( QgsDataItem *parent, QString name, QString path );
59+
QgsMssqlConnectionItem( QgsDataItem *parent, const QString &name, const QString &path );
6060
~QgsMssqlConnectionItem() override;
6161

6262
QVector<QgsDataItem *> createChildren() override;
@@ -109,7 +109,7 @@ class QgsMssqlSchemaItem : public QgsDataCollectionItem
109109
{
110110
Q_OBJECT
111111
public:
112-
QgsMssqlSchemaItem( QgsDataItem *parent, QString name, QString path );
112+
QgsMssqlSchemaItem( QgsDataItem *parent, const QString &name, const QString &path );
113113

114114
QVector<QgsDataItem *> createChildren() override;
115115

@@ -125,14 +125,17 @@ class QgsMssqlLayerItem : public QgsLayerItem
125125
Q_OBJECT
126126

127127
public:
128-
QgsMssqlLayerItem( QgsDataItem *parent, QString name, QString path, QgsLayerItem::LayerType layerType, QgsMssqlLayerProperty layerProperties );
128+
QgsMssqlLayerItem( QgsDataItem *parent, const QString &name, const QString &path, QgsLayerItem::LayerType layerType, const QgsMssqlLayerProperty &layerProperties );
129129

130130
QString createUri();
131131

132132
QgsMssqlLayerItem *createClone();
133133

134+
bool disableInvalidGeometryHandling() const;
135+
134136
private:
135137
QgsMssqlLayerProperty mLayerProperty;
138+
bool mDisableInvalidGeometryHandling = false;
136139
};
137140

138141
#endif // QGSMSSQLDATAITEMS_H

src/providers/mssql/qgsmssqlfeatureiterator.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
QgsMssqlFeatureIterator::QgsMssqlFeatureIterator( QgsMssqlFeatureSource *source, bool ownSource, const QgsFeatureRequest &request )
3232
: QgsAbstractFeatureIteratorFromSource<QgsMssqlFeatureSource>( source, ownSource, request )
33+
, mDisableInvalidGeometryHandling( source->mDisableInvalidGeometryHandling )
3334
{
3435
mClosed = false;
3536

@@ -141,7 +142,10 @@ void QgsMssqlFeatureIterator::BuildStatement( const QgsFeatureRequest &request )
141142
<< qgsDoubleToString( mFilterRect.xMinimum() ) << ' ' << qgsDoubleToString( mFilterRect.yMaximum() ) << ", "
142143
<< qgsDoubleToString( mFilterRect.xMinimum() ) << ' ' << qgsDoubleToString( mFilterRect.yMinimum() );
143144

144-
mStatement += QStringLiteral( " where [%1].STIsValid() = 1 AND [%1].STIntersects([%2]::STGeomFromText('POLYGON((%3))',%4)) = 1" ).arg(
145+
mStatement += QStringLiteral( " WHERE " );
146+
if ( !mDisableInvalidGeometryHandling )
147+
mStatement += QStringLiteral( "[%1].STIsValid() = 1 AND " ).arg( mSource->mGeometryColName );
148+
mStatement += QStringLiteral( "[%1].STIntersects([%2]::STGeomFromText('POLYGON((%3))',%4)) = 1" ).arg(
145149
mSource->mGeometryColName, mSource->mGeometryColType, r, QString::number( mSource->mSRId ) );
146150
filterAdded = true;
147151
}
@@ -495,6 +499,7 @@ QgsMssqlFeatureSource::QgsMssqlFeatureSource( const QgsMssqlProvider *p )
495499
, mDatabaseName( p->mDatabaseName )
496500
, mHost( p->mHost )
497501
, mSqlWhereClause( p->mSqlWhereClause )
502+
, mDisableInvalidGeometryHandling( p->mDisableInvalidGeometryHandling )
498503
, mCrs( p->crs() )
499504
{}
500505

src/providers/mssql/qgsmssqlfeatureiterator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class QgsMssqlFeatureSource : public QgsAbstractFeatureSource
6161
// SQL statement used to limit the features retrieved
6262
QString mSqlWhereClause;
6363

64+
bool mDisableInvalidGeometryHandling = false;
65+
6466
QgsCoordinateReferenceSystem mCrs;
6567

6668
// Return True if this feature source has spatial attributes.
@@ -116,6 +118,7 @@ class QgsMssqlFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsM
116118

117119
bool mExpressionCompiled = false;
118120
bool mOrderByCompiled = false;
121+
bool mDisableInvalidGeometryHandling = false;
119122

120123
QgsCoordinateTransform mTransform;
121124
QgsRectangle mFilterRect;

src/providers/mssql/qgsmssqlnewconnection.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ QgsMssqlNewConnection::QgsMssqlNewConnection( QWidget *parent, const QString &co
5252
cb_geometryColumns->setChecked( QgsMssqlConnection::geometryColumnsOnly( connName ) );
5353
cb_allowGeometrylessTables->setChecked( QgsMssqlConnection::allowGeometrylessTables( connName ) );
5454
cb_useEstimatedMetadata->setChecked( QgsMssqlConnection::useEstimatedMetadata( connName ) );
55+
mCheckNoInvalidGeometryHandling->setChecked( QgsMssqlConnection::isInvalidGeometryHandlingDisabled( connName ) );
5556

5657
if ( settings.value( key + "/saveUsername" ).toString() == QLatin1String( "true" ) )
5758
{
@@ -116,6 +117,7 @@ void QgsMssqlNewConnection::accept()
116117
QgsMssqlConnection::setGeometryColumnsOnly( connName, cb_geometryColumns->isChecked() );
117118
QgsMssqlConnection::setAllowGeometrylessTables( connName, cb_allowGeometrylessTables->isChecked() );
118119
QgsMssqlConnection::setUseEstimatedMetadata( connName, cb_useEstimatedMetadata->isChecked() );
120+
QgsMssqlConnection::setInvalidGeometryHandlingDisabled( connName, mCheckNoInvalidGeometryHandling->isChecked() );
119121

120122
QDialog::accept();
121123
}

src/providers/mssql/qgsmssqlprovider.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ QgsMssqlProvider::QgsMssqlProvider( const QString &uri, const ProviderOptions &o
8282

8383
mUseEstimatedMetadata = anUri.useEstimatedMetadata();
8484

85+
mDisableInvalidGeometryHandling = anUri.hasParam( QStringLiteral( "disableInvalidGeometryHandling" ) )
86+
? anUri.param( QStringLiteral( "disableInvalidGeometryHandling" ) ).toInt()
87+
: false;
88+
8589
mSqlWhereClause = anUri.sql();
8690

8791
mDatabase = QgsMssqlConnection::getDatabase( mService, mHost, mDatabaseName, mUserName, mPassword );
@@ -701,14 +705,29 @@ void QgsMssqlProvider::UpdateStatistics( bool estimate ) const
701705
if ( estimate )
702706
{
703707
if ( mGeometryColType == QLatin1String( "geometry" ) )
704-
statement = QStringLiteral( "select min([%1].MakeValid().STPointN(1).STX), min([%1].MakeValid().STPointN(1).STY), max([%1].MakeValid().STPointN(1).STX), max([%1].MakeValid().STPointN(1).STY)" ).arg( mGeometryColName );
708+
{
709+
if ( mDisableInvalidGeometryHandling )
710+
statement = QStringLiteral( "select min([%1].STPointN(1).STX), min([%1].STPointN(1).STY), max([%1].STPointN(1).STX), max([%1].STPointN(1).STY)" ).arg( mGeometryColName );
711+
else
712+
statement = QStringLiteral( "select min(case when ([%1].STIsValid() = 1) THEN [%1].STPointN(1).STX else NULL end), min(case when ([%1].STIsValid() = 1) THEN [%1].STPointN(1).STY else NULL end), max(case when ([%1].STIsValid() = 1) THEN [%1].STPointN(1).STX else NULL end), max(case when ([%1].STIsValid() = 1) THEN [%1].STPointN(1).STY else NULL end)" ).arg( mGeometryColName );
713+
}
705714
else
706-
statement = QStringLiteral( "select min([%1].MakeValid().STPointN(1).Long), min([%1].MakeValid().STPointN(1).Lat), max([%1].MakeValid().STPointN(1).Long), max([%1].MakeValid().STPointN(1).Lat)" ).arg( mGeometryColName );
715+
{
716+
if ( mDisableInvalidGeometryHandling )
717+
statement = QStringLiteral( "select min([%1].STPointN(1).Long), min([%1].STPointN(1).Lat), max([%1].STPointN(1).Long), max([%1].STPointN(1).Lat)" ).arg( mGeometryColName );
718+
else
719+
statement = QStringLiteral( "select min(case when ([%1].STIsValid() = 1) THEN [%1].STPointN(1).Long else NULL end), min(case when ([%1].STIsValid() = 1) THEN [%1].STPointN(1).Lat else NULL end), max(case when ([%1].STIsValid() = 1) THEN [%1].STPointN(1).Long else NULL end), max(case when ([%1].STIsValid() = 1) THEN [%1].STPointN(1).Lat else NULL end)" ).arg( mGeometryColName );
720+
}
707721
}
708722
else
709723
{
710724
if ( mGeometryColType == QLatin1String( "geometry" ) )
711-
statement = QStringLiteral( "select min([%1].MakeValid().STEnvelope().STPointN(1).STX), min([%1].MakeValid().STEnvelope().STPointN(1).STY), max([%1].MakeValid().STEnvelope().STPointN(3).STX), max([%1].MakeValid().STEnvelope().STPointN(3).STY)" ).arg( mGeometryColName );
725+
{
726+
if ( mDisableInvalidGeometryHandling )
727+
statement = QStringLiteral( "select min(case when ([%1].STIsValid() = 1) THEN [%1].STEnvelope().STPointN(1).STX else NULL end), min(case when ([%1].STIsValid() = 1) THEN [%1].STEnvelope().STPointN(1).STY else NULL end), max(case when ([%1].STIsValid() = 1) THEN [%1].STEnvelope().STPointN(3).STX else NULL end), max(case when ([%1].STIsValid() = 1) THEN [%1].STEnvelope().STPointN(3).STY else NULL end)" ).arg( mGeometryColName );
728+
else
729+
statement = QStringLiteral( "select min([%1].STEnvelope().STPointN(1).STX), min([%1].STEnvelope().STPointN(1).STY), max([%1].STEnvelope().STPointN(3).STX), max([%1].STEnvelope().STPointN(3).STY)" ).arg( mGeometryColName );
730+
}
712731
else
713732
{
714733
statement = QStringLiteral( "select [%1]" ).arg( mGeometryColName );

src/providers/mssql/qgsmssqlprovider.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ class QgsMssqlProvider : public QgsVectorDataProvider
205205
// SQL statement used to limit the features retrieved
206206
QString mSqlWhereClause;
207207

208+
bool mDisableInvalidGeometryHandling = false;
209+
208210
// Sets the error messages
209211
void setLastError( const QString &error );
210212

0 commit comments

Comments
 (0)