Skip to content

Commit

Permalink
[mssql] Don't query ALL tables to retrieve single table details
Browse files Browse the repository at this point in the history
Lightens load when browsing SQL Server connections via browser
  • Loading branch information
nyalldawson committed Feb 23, 2025
1 parent 8789841 commit 19df56c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
35 changes: 29 additions & 6 deletions src/providers/mssql/qgsmssqlproviderconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,23 +330,41 @@ long long QgssMssqlProviderResultIterator::rowCountPrivate() const
return mQuery->size();
}

QgsAbstractDatabaseProviderConnection::TableProperty QgsMssqlProviderConnection::table( const QString &schema, const QString &table, QgsFeedback *feedback ) const
{
const QList<QgsMssqlProviderConnection::TableProperty> properties { tablesPrivate( schema, table, TableFlags(), feedback ) };
if ( !properties.empty() )
{
return properties.first();
}
else
{
throw QgsProviderConnectionException( QObject::tr( "Table '%1' was not found in schema '%2'" )
.arg( table, schema ) );
}
}

QList<QgsMssqlProviderConnection::TableProperty> QgsMssqlProviderConnection::tables( const QString &schema, const TableFlags &flags, QgsFeedback *feedback ) const
{
return tablesPrivate( schema, QString(), flags, feedback );
}

QList<QgsAbstractDatabaseProviderConnection::TableProperty> QgsMssqlProviderConnection::tablesPrivate( const QString &schema, const QString &table, const TableFlags &flags, QgsFeedback *feedback ) const
{
checkCapability( Capability::Tables );
QList<QgsMssqlProviderConnection::TableProperty> tables;

const QgsDataSourceUri dsUri { uri() };

// Defaults to false
const bool useGeometryColumnsOnly { dsUri.hasParam( QStringLiteral( "geometryColumnsOnly" ) ) && ( dsUri.param( QStringLiteral( "geometryColumnsOnly" ) ) == QLatin1String( "true" ) || dsUri.param( QStringLiteral( "geometryColumnsOnly" ) ) == '1' ) };
const bool useGeometryColumnsOnly { !table.isEmpty() && ( dsUri.hasParam( QStringLiteral( "geometryColumnsOnly" ) ) && ( dsUri.param( QStringLiteral( "geometryColumnsOnly" ) ) == QLatin1String( "true" ) || dsUri.param( QStringLiteral( "geometryColumnsOnly" ) ) == '1' ) ) };

// Defaults to true
const bool useEstimatedMetadata { !dsUri.hasParam( QStringLiteral( "estimatedMetadata" ) ) || ( dsUri.param( QStringLiteral( "estimatedMetadata" ) ) == QLatin1String( "true" ) || dsUri.param( QStringLiteral( "estimatedMetadata" ) ) == '1' ) };

// Defaults to true because we want to list all tables if flags are not set
bool allowGeometrylessTables;
if ( flags == 0 )
if ( flags == 0 || !table.isEmpty() )
{
allowGeometrylessTables = true;
}
Expand All @@ -355,6 +373,11 @@ QList<QgsMssqlProviderConnection::TableProperty> QgsMssqlProviderConnection::tab
allowGeometrylessTables = flags.testFlag( TableFlag::Aspatial );
}
const bool disableInvalidGeometryHandling = dsUri.hasParam( QStringLiteral( "disableInvalidGeometryHandling" ) ) && dsUri.param( QStringLiteral( "disableInvalidGeometryHandling" ) ).toInt();
QString tableNameFilter;
if ( !table.isEmpty() )
{
tableNameFilter = QStringLiteral( " AND sys.objects.name = %1" ).arg( QgsMssqlProvider::quotedValue( table ) );
}

QString query { QStringLiteral( "SELECT " ) };

Expand All @@ -375,11 +398,11 @@ QList<QgsMssqlProviderConnection::TableProperty> QgsMssqlProviderConnection::tab
JOIN sys.schemas
ON sys.objects.schema_id = sys.schemas.schema_id
WHERE
sys.schemas.name = %1
sys.schemas.name = %1 %2
AND (sys.types.name = 'geometry' OR sys.types.name = 'geography')
AND (sys.objects.type = 'U' OR sys.objects.type = 'V')
)raw" )
.arg( QgsMssqlProvider::quotedValue( schema ) );
.arg( QgsMssqlProvider::quotedValue( schema ), tableNameFilter );
}

if ( allowGeometrylessTables )
Expand All @@ -391,15 +414,15 @@ QList<QgsMssqlProviderConnection::TableProperty> QgsMssqlProviderConnection::tab
JOIN sys.schemas
ON sys.objects.schema_id = sys.schemas.schema_id
WHERE
sys.schemas.name = %1
sys.schemas.name = %1 %2
AND 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')
)raw" )
.arg( QgsMssqlProvider::quotedValue( schema ) );
.arg( QgsMssqlProvider::quotedValue( schema ), tableNameFilter );
}

const QList<QVariantList> results { executeSqlPrivate( query, false ).rows() };
Expand Down
2 changes: 2 additions & 0 deletions src/providers/mssql/qgsmssqlproviderconnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class QgsMssqlProviderConnection : public QgsAbstractDatabaseProviderConnection
void dropSchema( const QString &name, bool force = false ) const override;
QgsAbstractDatabaseProviderConnection::QueryResult execSql( const QString &sql, QgsFeedback *feedback ) const override;
QList<QgsAbstractDatabaseProviderConnection::TableProperty> tables( const QString &schema, const TableFlags &flags = TableFlags(), QgsFeedback *feedback = nullptr ) const override;
QgsAbstractDatabaseProviderConnection::TableProperty table( const QString &schema, const QString &table, QgsFeedback *feedback = nullptr ) const override;
QStringList schemas() const override;
void store( const QString &name ) const override;
void remove( const QString &name ) const override;
Expand All @@ -72,6 +73,7 @@ class QgsMssqlProviderConnection : public QgsAbstractDatabaseProviderConnection
void setDefaultCapabilities();
void dropTablePrivate( const QString &schema, const QString &name ) const;
void renameTablePrivate( const QString &schema, const QString &name, const QString &newName ) const;
QList<QgsAbstractDatabaseProviderConnection::TableProperty> tablesPrivate( const QString &schema, const QString &table, const TableFlags &flags = TableFlags(), QgsFeedback *feedback = nullptr ) const;

static const QStringList EXTRA_CONNECTION_PARAMETERS;
};
Expand Down

0 comments on commit 19df56c

Please sign in to comment.