Skip to content

Commit

Permalink
Fix virtual layers using joined fields
Browse files Browse the repository at this point in the history
Fix #46834
  • Loading branch information
elpaso authored and troopa81 committed Jan 24, 2022
1 parent 5cdd5b5 commit 4fd2f04
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/core/project/qgsproject.cpp
Expand Up @@ -39,6 +39,7 @@
#include "qgsrelationmanager.h"
#include "qgsannotationmanager.h"
#include "qgsvectorlayerjoininfo.h"
#include "qgsvectorlayerjoinbuffer.h"
#include "qgsmapthemecollection.h"
#include "qgslayerdefinition.h"
#include "qgsunittypes.h"
Expand Down Expand Up @@ -1264,6 +1265,14 @@ bool QgsProject::addLayer( const QDomElement &layerElem, QList<QDomNode> &broken
{
emit readMapLayer( mapLayer.get(), layerElem );
addMapLayers( newLayers );
// Try to resolve references here (this is necessary to set up joined fields that will be possibly used by
// virtual layers that point to this layer's joined field in their query otherwise they won't be valid ),
// a second attempt to resolve references will be done after all layers are loaded
// see https://github.com/qgis/QGIS/issues/46834
if ( QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( mapLayer.get() ) )
{
vLayer->joinBuffer()->resolveReferences( this );
}
}
else
{
Expand Down
39 changes: 39 additions & 0 deletions tests/src/python/test_provider_virtual.py
Expand Up @@ -1366,6 +1366,45 @@ def test_layer_starting_with_digit(self):
vl = QgsVectorLayer(df.toString(), "1_layer_virtual", "virtual")
self.assertTrue(vl.isValid())

def test_layer_using_joined_fields_from_another_layer(self):
"""Test issue GH #46834"""

project = QgsProject.instance()
project.clear()
layer_1 = QgsVectorLayer('Point?crs=epsg:4326&field=fid:integer', 'layer_1', 'memory')
layer_2 = QgsVectorLayer('Point?crs=epsg:4326&field=fid:integer', 'layer_2', 'memory')

project.addMapLayers([layer_1])

# Add a join from 2 to 1
join_info = QgsVectorLayerJoinInfo()
join_info.setJoinLayer(layer_1)
join_info.setJoinFieldName('layer_1_fid')
join_info.setTargetFieldName('fid')
self.assertTrue(layer_2.addJoin(join_info))
self.assertIn('layer_1_fid', layer_2.fields().names())

project.addMapLayers([layer_2])

df = QgsVirtualLayerDefinition()
df.setQuery('select fid, layer_1_fid from "layer_2"')
vl = QgsVectorLayer(df.toString(), "virtual", "virtual")
self.assertTrue(vl.isValid())

project.addMapLayers([vl])

tmp = QTemporaryDir()
path = tmp.path()
project.write(os.path.join(path, 'test_4683.qgs'))

project.clear()
project.read(os.path.join(path, 'test_4683.qgs'))

layer_2 = project.mapLayersByName('layer_2')[0]
vl = project.mapLayersByName('virtual')[0]

self.assertTrue(vl.isValid())


if __name__ == '__main__':
unittest.main()

0 comments on commit 4fd2f04

Please sign in to comment.