@@ -568,52 +568,55 @@ void QgsMssqlProvider::uniqueValues( int index, QList<QVariant> &uniqueValues, i
568
568
}
569
569
570
570
571
- // update the extent, feature count, wkb type and srid for this layer
571
+ // update the extent, wkb type and srid for this layer
572
572
void QgsMssqlProvider::UpdateStatistics ( bool estimate )
573
573
{
574
- mNumberFeatures = 0 ;
575
574
// get features to calculate the statistics
576
575
QString statement;
577
576
578
577
QSqlQuery query = QSqlQuery ( mDatabase );
579
578
query.setForwardOnly ( true );
580
579
581
- // Get the extents from the geometry_columns table to speed up load times.
582
- statement = QString ( " SELECT min_x, min_y, max_x, max_y from geometry_columns where f_table_schema = '%1' and f_table_name = '%2'" ).arg ( mSchemaName ).arg ( mTableName );
580
+ // Get the extents from the spatial index table to speed up load times.
581
+ // We have to use max() and min() because you can have more then one index but the biggest area is what we want to use.
582
+ QString sql = " SELECT min(bounding_box_xmin), min(bounding_box_ymin), max(bounding_box_xmax), max(bounding_box_ymax)"
583
+ " FROM sys.spatial_index_tessellations WHERE object_id = OBJECT_ID('[%1].[%2]')" ;
584
+
585
+ statement = QString (sql).arg ( mSchemaName )
586
+ .arg ( mTableName );
583
587
584
588
if ( query.exec ( statement ) )
585
589
{
590
+ QgsDebugMsg (" Found extents in spatial index" );
586
591
if ( query.next () )
587
592
{
588
- if ( !query.value ( 0 ).isNull () || !query.value ( 1 ).isNull () ||
589
- !query.value ( 2 ).isNull () || !query.value ( 3 ).isNull () )
590
- {
591
593
mExtent .setXMinimum ( query.value ( 0 ).toDouble () );
592
594
mExtent .setYMinimum ( query.value ( 1 ).toDouble () );
593
595
mExtent .setXMaximum ( query.value ( 2 ).toDouble () );
594
596
mExtent .setYMaximum ( query.value ( 3 ).toDouble () );
595
597
return ;
596
- }
597
598
}
598
599
}
599
600
600
- // If we can't find the extents in the geometry_columns table just do what we normally do.
601
- bool readAll = false ;
601
+ QgsDebugMsg (query.lastError ().text ());
602
+
603
+ // If we can't find the extents in the spatial index table just do what we normally do.
604
+ bool readAllGeography = false ;
602
605
if ( estimate )
603
606
{
604
607
if ( mGeometryColType == " geometry" )
605
- statement = QString ( " select min([%1].STPointN(1).STX), min([%1].STPointN(1).STY), max([%1].STPointN(1).STX), max([%1].STPointN(1).STY), COUNT([%1]) " ).arg ( mGeometryColName );
608
+ statement = QString ( " select min([%1].STPointN(1).STX), min([%1].STPointN(1).STY), max([%1].STPointN(1).STX), max([%1].STPointN(1).STY)" ).arg ( mGeometryColName );
606
609
else
607
- statement = QString ( " select min([%1].STPointN(1).Long), min([%1].STPointN(1).Lat), max([%1].STPointN(1).Long), max([%1].STPointN(1).Lat), COUNT([%1]) " ).arg ( mGeometryColName );
610
+ statement = QString ( " select min([%1].STPointN(1).Long), min([%1].STPointN(1).Lat), max([%1].STPointN(1).Long), max([%1].STPointN(1).Lat)" ).arg ( mGeometryColName );
608
611
}
609
612
else
610
613
{
611
614
if ( mGeometryColType == " geometry" )
612
- statement = QString ( " 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), count([%1]) " ).arg ( mGeometryColName );
615
+ statement = QString ( " 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 );
613
616
else
614
617
{
615
618
statement = QString ( " select [%1]" ).arg ( mGeometryColName );
616
- readAll = true ;
619
+ readAllGeography = true ;
617
620
}
618
621
}
619
622
@@ -633,52 +636,45 @@ void QgsMssqlProvider::UpdateStatistics( bool estimate )
633
636
QgsDebugMsg ( msg );
634
637
}
635
638
636
- if ( query.isActive () )
639
+ if ( !query.isActive () )
640
+ {
641
+ return ;
642
+ }
643
+
644
+ QgsGeometry geom;
645
+ if ( !readAllGeography )
637
646
{
638
- QgsGeometry geom;
639
- if ( !readAll )
647
+ if ( query.next () )
640
648
{
641
- if ( query.next () )
642
- {
643
- mExtent .setXMinimum ( query.value ( 0 ).toDouble () );
644
- mExtent .setYMinimum ( query.value ( 1 ).toDouble () );
645
- mExtent .setXMaximum ( query.value ( 2 ).toDouble () );
646
- mExtent .setYMaximum ( query.value ( 3 ).toDouble () );
647
- mNumberFeatures = query.value ( 4 ).toInt ();
648
- }
649
+ mExtent .setXMinimum ( query.value ( 0 ).toDouble () );
650
+ mExtent .setYMinimum ( query.value ( 1 ).toDouble () );
651
+ mExtent .setXMaximum ( query.value ( 2 ).toDouble () );
652
+ mExtent .setYMaximum ( query.value ( 3 ).toDouble () );
653
+ return ;
649
654
}
650
- else
651
- {
652
- // read all features
653
- while ( query.next () )
654
- {
655
- QByteArray ar = query.value ( 0 ).toByteArray ();
656
- unsigned char * wkb = parser.ParseSqlGeometry (( unsigned char * )ar.data (), ar.size () );
657
- if ( wkb )
658
- {
659
- geom.fromWkb ( wkb, parser.GetWkbLen () );
660
- QgsRectangle rect = geom.boundingBox ();
655
+ }
661
656
662
- if ( mNumberFeatures > 0 )
663
- {
664
- if ( rect.xMinimum () < mExtent .xMinimum () )
665
- mExtent .setXMinimum ( rect.xMinimum () );
666
- if ( rect.yMinimum () < mExtent .yMinimum () )
667
- mExtent .setYMinimum ( rect.yMinimum () );
668
- if ( rect.xMaximum () > mExtent .xMaximum () )
669
- mExtent .setXMaximum ( rect.xMaximum () );
670
- if ( rect.yMaximum () > mExtent .yMaximum () )
671
- mExtent .setYMaximum ( rect.yMaximum () );
672
- }
673
- else
674
- {
675
- mExtent = rect;
676
- mWkbType = geom.wkbType ();
677
- mSRId = parser.GetSRSId ();
678
- }
679
- ++mNumberFeatures ;
680
- }
681
- }
657
+ // We have to read all the geometry if readAllGeography is true.
658
+ while ( query.next () )
659
+ {
660
+ QByteArray ar = query.value ( 0 ).toByteArray ();
661
+ unsigned char * wkb = parser.ParseSqlGeometry (( unsigned char * )ar.data (), ar.size () );
662
+ if ( wkb )
663
+ {
664
+ geom.fromWkb ( wkb, parser.GetWkbLen () );
665
+ QgsRectangle rect = geom.boundingBox ();
666
+
667
+ if ( rect.xMinimum () < mExtent .xMinimum () )
668
+ mExtent .setXMinimum ( rect.xMinimum () );
669
+ if ( rect.yMinimum () < mExtent .yMinimum () )
670
+ mExtent .setYMinimum ( rect.yMinimum () );
671
+ if ( rect.xMaximum () > mExtent .xMaximum () )
672
+ mExtent .setXMaximum ( rect.xMaximum () );
673
+ if ( rect.yMaximum () > mExtent .yMaximum () )
674
+ mExtent .setYMaximum ( rect.yMaximum () );
675
+
676
+ mWkbType = geom.wkbType ();
677
+ mSRId = parser.GetSRSId ();
682
678
}
683
679
}
684
680
}
@@ -704,7 +700,36 @@ QGis::WkbType QgsMssqlProvider::geometryType() const
704
700
*/
705
701
long QgsMssqlProvider::featureCount () const
706
702
{
707
- return mNumberFeatures ;
703
+ // Return the count that we get from the subset.
704
+ if ( !mSqlWhereClause .isEmpty () )
705
+ return mNumberFeatures ;
706
+
707
+ // If there is no subset set we can get the count from the system tables.
708
+ // Which is faster then doing select count(*)
709
+ QSqlQuery query = QSqlQuery ( mDatabase );
710
+ query.setForwardOnly ( true );
711
+
712
+ QString sql = " SELECT rows"
713
+ " FROM sys.tables t"
714
+ " JOIN sys.partitions p ON t.object_id = p.object_id AND p.index_id IN (0,1)"
715
+ " WHERE SCHEMA_NAME(t.schema_id) = '%1' AND OBJECT_NAME(t.OBJECT_ID) = '%2'" ;
716
+
717
+ QString statement = QString (sql).arg ( mSchemaName )
718
+ .arg ( mTableName );
719
+
720
+ if ( query.exec ( statement ) )
721
+ {
722
+ if ( query.next () )
723
+ {
724
+ return query.value (0 ).toInt ();
725
+ }
726
+ }
727
+ else
728
+ {
729
+ // We couldn't get the rows from the sys tables. Can that ever happen?
730
+ // Should just do a select count(*) here.
731
+ return -1 ;
732
+ }
708
733
}
709
734
710
735
const QgsFields & QgsMssqlProvider::fields () const
0 commit comments