Skip to content

Commit

Permalink
Fix wrong attr values in joined fields
Browse files Browse the repository at this point in the history
If the joined layer has field names that collide with already existing 
fields, these fields from the joined layer are dropped. However, this 
situation was not handled in the code, as the real joined field attr 
index is not being used, but indices starting from 0, 1, 2 for each 
of the joined fields. 

For example: 
"joined" layer has fields "id", "name" and "descr";
"source" layer has fields "id", "name", "joined_id"

Then "id" and "name" column from "joined" will be discarded, but the
the value for "descr" would not be taken from attribute index 2, but
index 2.

Fix #26652
  • Loading branch information
suricactus committed Jan 27, 2021
1 parent d821f0a commit 3b54697
Showing 1 changed file with 13 additions and 17 deletions.
30 changes: 13 additions & 17 deletions src/core/vector/qgsvectorlayerfeatureiterator.cpp
Expand Up @@ -1076,15 +1076,24 @@ void QgsVectorLayerFeatureIterator::FetchJoinInfo::addJoinedAttributesDirect( Qg
subsetString += '=' + v;
}

QList<int> joinedAttributeIndices;

// maybe user requested just a subset of layer's attributes
// so we do not have to cache everything
QVector<int> subsetIndices;
if ( joinInfo->hasSubset() )
{
const QStringList subsetNames = QgsVectorLayerJoinInfo::joinFieldNamesSubset( *joinInfo );
subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, subsetNames );
QVector<int> subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, subsetNames );
joinedAttributeIndices = attributes.toSet().intersect( subsetIndices.toList().toSet() ).toList();
}
else
{
joinedAttributeIndices = attributes.toVector().toList();
}

// we don't need the join field, it is already present in the other table
joinedAttributeIndices.removeAll( joinField );

// select (no geometry)
QgsFeatureRequest request;
request.setFlags( QgsFeatureRequest::NoGeometry );
Expand All @@ -1099,22 +1108,9 @@ void QgsVectorLayerFeatureIterator::FetchJoinInfo::addJoinedAttributesDirect( Qg
{
int index = indexOffset;
QgsAttributes attr = fet.attributes();
if ( joinInfo->hasSubset() )
{
for ( int i = 0; i < subsetIndices.count(); ++i )
f.setAttribute( index++, attr.at( subsetIndices.at( i ) ) );
}
else
{
// use all fields except for the one used for join (has same value as exiting field in target layer)
for ( int i = 0; i < attr.count(); ++i )
{
if ( i == joinField )
continue;

f.setAttribute( index++, attr.at( i ) );
}
}
for ( int i = 0; i < joinedAttributeIndices.count(); ++i )
f.setAttribute( index++, attr.at( joinedAttributeIndices.at( i ) ) );
}
else
{
Expand Down

0 comments on commit 3b54697

Please sign in to comment.