Skip to content

Commit

Permalink
Cache only joined attributes without colliding names. Fix #45169
Browse files Browse the repository at this point in the history
  • Loading branch information
domi4484 authored and nyalldawson committed Sep 28, 2021
1 parent c3ac518 commit e9fd2dd
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/core/vector/qgsvectorlayerjoinbuffer.cpp
Expand Up @@ -172,9 +172,14 @@ void QgsVectorLayerJoinBuffer::cacheJoinLayer( QgsVectorLayerJoinInfo &joinInfo
}
else
{
QgsAttributes attrs2 = attrs;
attrs2.remove( joinFieldIndex ); // skip the join field to avoid double field names (fields often have the same name)
joinInfo.cachedAttributes.insert( key, attrs2 );
QgsAttributes attributesCache;
for ( int i = 0; i < attrs.size(); i++ )
{
if ( i != joinFieldIndex
&& !mLayer->fields().names().contains( cacheLayer->fields().names().at( i ) ) )
attributesCache.append( attrs.at( i ) );
}
joinInfo.cachedAttributes.insert( key, attributesCache );
}
}
joinInfo.cacheDirty = false;
Expand Down
44 changes: 44 additions & 0 deletions tests/src/core/testqgsvectorlayerjoinbuffer.cpp
Expand Up @@ -69,6 +69,7 @@ class TestVectorLayerJoinBuffer : public QObject
void testSignals();
void testChangeAttributeValues();
void testCollidingNameColumn();
void testCollidingNameColumnCached();

private:
QgsProject mProject;
Expand Down Expand Up @@ -978,5 +979,48 @@ void TestVectorLayerJoinBuffer::testCollidingNameColumn()
QCOMPARE( fA1.attribute( "value_c" ).toString(), QStringLiteral( "value_c" ) );
}

void TestVectorLayerJoinBuffer::testCollidingNameColumnCached()
{
mProject.clear();
QgsVectorLayer *vlA = new QgsVectorLayer( QStringLiteral( "Point?field=id_a:integer&field=name" ), QStringLiteral( "cacheA" ), QStringLiteral( "memory" ) );
QVERIFY( vlA->isValid() );
QgsVectorLayer *vlB = new QgsVectorLayer( QStringLiteral( "Point?field=id_b:integer&field=name&field=value_b&field=value_c" ), QStringLiteral( "cacheB" ), QStringLiteral( "memory" ) );
QVERIFY( vlB->isValid() );
mProject.addMapLayer( vlA );
mProject.addMapLayer( vlB );

QgsFeature fA1( vlA->dataProvider()->fields(), 1 );
fA1.setAttribute( QStringLiteral( "id_a" ), 1 );
fA1.setAttribute( QStringLiteral( "name" ), QStringLiteral( "name_a" ) );

vlA->dataProvider()->addFeatures( QgsFeatureList() << fA1 );

QgsFeature fB1( vlB->dataProvider()->fields(), 1 );
fB1.setAttribute( QStringLiteral( "id_b" ), 1 );
fB1.setAttribute( QStringLiteral( "name" ), QStringLiteral( "name_b" ) );
fB1.setAttribute( QStringLiteral( "value_b" ), QStringLiteral( "value_b" ) );
fB1.setAttribute( QStringLiteral( "value_c" ), QStringLiteral( "value_c" ) );

vlB->dataProvider()->addFeatures( QgsFeatureList() << fB1 );

QgsVectorLayerJoinInfo joinInfo;
joinInfo.setTargetFieldName( QStringLiteral( "id_a" ) );
joinInfo.setJoinLayer( vlB );
joinInfo.setJoinFieldName( QStringLiteral( "id_b" ) );
joinInfo.setPrefix( QStringLiteral( "" ) );
joinInfo.setEditable( true );
joinInfo.setUpsertOnEdit( false );
joinInfo.setUsingMemoryCache( true );
vlA->addJoin( joinInfo );

QgsFeatureIterator fi1 = vlA->getFeatures();
fi1.nextFeature( fA1 );
QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b", "value_c"} ) );
QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 );
QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) );
QCOMPARE( fA1.attribute( "value_b" ).toString(), QStringLiteral( "value_b" ) );
QCOMPARE( fA1.attribute( "value_c" ).toString(), QStringLiteral( "value_c" ) );
}

QGSTEST_MAIN( TestVectorLayerJoinBuffer )
#include "testqgsvectorlayerjoinbuffer.moc"

0 comments on commit e9fd2dd

Please sign in to comment.