@@ -555,6 +555,7 @@ void QgsVectorLayerFeatureIterator::prepareFields()
555
555
mPreparedFields .clear ();
556
556
mFieldsToPrepare .clear ();
557
557
mFetchJoinInfo .clear ();
558
+ mOrderedJoinInfoList .clear ();
558
559
559
560
mExpressionContext .reset ( new QgsExpressionContext () );
560
561
mExpressionContext ->appendScope ( QgsExpressionContextUtils::globalScope () );
@@ -572,6 +573,70 @@ void QgsVectorLayerFeatureIterator::prepareFields()
572
573
mPreparedFields << fieldIdx;
573
574
prepareField ( fieldIdx );
574
575
}
576
+
577
+ // sort joins by dependency
578
+ if ( mFetchJoinInfo .size () > 0 )
579
+ {
580
+ createOrderedJoinList ();
581
+ }
582
+ }
583
+
584
+ void QgsVectorLayerFeatureIterator::createOrderedJoinList ()
585
+ {
586
+ mOrderedJoinInfoList = mFetchJoinInfo .values ();
587
+ if ( mOrderedJoinInfoList .size () < 2 )
588
+ {
589
+ return ;
590
+ }
591
+
592
+ QSet<int > resolvedFields; // todo: get provider / virtual fields without joins
593
+
594
+ // add all provider fields without joins as resolved fields
595
+ QList< int >::const_iterator prepFieldIt = mPreparedFields .constBegin ();
596
+ for ( ; prepFieldIt != mPreparedFields .constEnd (); ++prepFieldIt )
597
+ {
598
+ if ( mSource ->mFields .fieldOrigin ( *prepFieldIt ) != QgsFields::OriginJoin )
599
+ {
600
+ resolvedFields.insert ( *prepFieldIt );
601
+ }
602
+ }
603
+
604
+ // iterate through the joins. If target field is not yet covered, move the entry to the end of the list
605
+
606
+ // some join combinations might not have a resolution at all
607
+ int maxIterations = ( mOrderedJoinInfoList .size () + 1 ) * mOrderedJoinInfoList .size () / 2.0 ;
608
+ int currentIteration = 0 ;
609
+
610
+ for ( int i = 0 ; i < mOrderedJoinInfoList .size () - 1 ; ++i )
611
+ {
612
+ if ( !resolvedFields.contains ( mOrderedJoinInfoList .at ( i ).targetField ) )
613
+ {
614
+ mOrderedJoinInfoList .append ( mOrderedJoinInfoList .at ( i ) );
615
+ mOrderedJoinInfoList .removeAt ( i );
616
+ --i;
617
+ }
618
+ else
619
+ {
620
+ int offset = mOrderedJoinInfoList .at ( i ).indexOffset ;
621
+ int joinField = mOrderedJoinInfoList .at ( i ).joinField ;
622
+
623
+ QgsAttributeList attributes = mOrderedJoinInfoList .at ( i ).attributes ;
624
+ QgsAttributeList::const_iterator attIt = attributes.constBegin ();
625
+ for ( ; attIt != attributes.constEnd (); ++attIt )
626
+ {
627
+ if ( *attIt != joinField )
628
+ {
629
+ resolvedFields.insert ( joinField < *attIt ? *attIt + offset - 1 : *attIt + offset );
630
+ }
631
+ }
632
+ }
633
+
634
+ ++currentIteration;
635
+ if ( currentIteration >= maxIterations )
636
+ {
637
+ break ;
638
+ }
639
+ }
575
640
}
576
641
577
642
void QgsVectorLayerFeatureIterator::prepareField ( int fieldIdx )
@@ -598,21 +663,19 @@ void QgsVectorLayerFeatureIterator::prepareField( int fieldIdx )
598
663
599
664
void QgsVectorLayerFeatureIterator::addJoinedAttributes ( QgsFeature &f )
600
665
{
601
- QMap< const QgsVectorJoinInfo*, FetchJoinInfo>::const_iterator joinIt = mFetchJoinInfo .constBegin ();
602
- for ( ; joinIt != mFetchJoinInfo .constEnd (); ++joinIt )
666
+ QList< FetchJoinInfo >::const_iterator joinIt = mOrderedJoinInfoList .constBegin ();
667
+ for ( ; joinIt != mOrderedJoinInfoList .constEnd (); ++joinIt )
603
668
{
604
- const FetchJoinInfo& info = joinIt.value ();
605
- Q_ASSERT ( joinIt.key () );
669
+ QVariant targetFieldValue = f.attribute ( joinIt->targetField );
606
670
607
- QVariant targetFieldValue = f.attribute ( info.targetField );
608
671
if ( !targetFieldValue.isValid () )
609
672
continue ;
610
673
611
- const QHash< QString, QgsAttributes>& memoryCache = info. joinInfo ->cachedAttributes ;
674
+ const QHash< QString, QgsAttributes>& memoryCache = joinIt-> joinInfo ->cachedAttributes ;
612
675
if ( memoryCache.isEmpty () )
613
- info. addJoinedAttributesDirect ( f, targetFieldValue );
676
+ joinIt-> addJoinedAttributesDirect ( f, targetFieldValue );
614
677
else
615
- info. addJoinedAttributesCached ( f, targetFieldValue );
678
+ joinIt-> addJoinedAttributesCached ( f, targetFieldValue );
616
679
}
617
680
}
618
681
0 commit comments