From 6461d3daa0632bb7c954685a9d41d775bb93b00c Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 14 Oct 2020 09:42:43 +1000 Subject: [PATCH] [processing] Correctly discard fid field values when running algorithms with the RegeneratePrimaryKey flag in in-place mode Fixes #37761, fixes #33816 --- python/plugins/processing/gui/AlgorithmExecutor.py | 6 +++++- src/core/processing/qgsprocessingutils.cpp | 2 ++ tests/src/analysis/testqgsprocessing.cpp | 4 +++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/python/plugins/processing/gui/AlgorithmExecutor.py b/python/plugins/processing/gui/AlgorithmExecutor.py index 599ef0c000d3..36e5195b071a 100644 --- a/python/plugins/processing/gui/AlgorithmExecutor.py +++ b/python/plugins/processing/gui/AlgorithmExecutor.py @@ -240,9 +240,13 @@ def execute_in_place_run(alg, parameters, context=None, feedback=None, raise_exc active_layer.deleteFeatures(active_layer.selectedFeatureIds()) + regenerate_primary_key = result_layer.customProperty('OnConvertFormatRegeneratePrimaryKey', False) + sink_flags = QgsFeatureSink.SinkFlags(QgsFeatureSink.RegeneratePrimaryKey) if regenerate_primary_key \ + else QgsFeatureSink.SinkFlags() + for f in result_layer.getFeatures(): new_features.extend(QgsVectorLayerUtils. - makeFeaturesCompatible([f], active_layer)) + makeFeaturesCompatible([f], active_layer, sink_flags)) # Get the new ids old_ids = set([f.id() for f in active_layer.getFeatures(req)]) diff --git a/src/core/processing/qgsprocessingutils.cpp b/src/core/processing/qgsprocessingutils.cpp index 6198194dd693..b33d0f63c69d 100644 --- a/src/core/processing/qgsprocessingutils.cpp +++ b/src/core/processing/qgsprocessingutils.cpp @@ -715,6 +715,8 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, Qgs throw QgsProcessingException( QObject::tr( "Could not create memory layer" ) ); } + layer->setCustomProperty( QStringLiteral( "OnConvertFormatRegeneratePrimaryKey" ), static_cast< bool >( sinkFlags & QgsFeatureSink::RegeneratePrimaryKey ) ); + // update destination to layer ID destination = layer->id(); diff --git a/tests/src/analysis/testqgsprocessing.cpp b/tests/src/analysis/testqgsprocessing.cpp index 487e0618d488..8db51c707820 100644 --- a/tests/src/analysis/testqgsprocessing.cpp +++ b/tests/src/analysis/testqgsprocessing.cpp @@ -1808,6 +1808,7 @@ void TestQgsProcessing::createFeatureSink() QCOMPARE( static_cast< QgsProxyFeatureSink *>( sink.get() )->destinationSink(), layer->dataProvider() ); QCOMPARE( layer->dataProvider()->name(), QStringLiteral( "memory" ) ); QCOMPARE( destination, layer->id() ); + QVERIFY( !layer->customProperty( QStringLiteral( "OnConvertFormatRegeneratePrimaryKey" ) ).toBool() ); QCOMPARE( context.temporaryLayerStore()->mapLayer( layer->id() ), layer ); // layer should be in store QgsFeature f; QCOMPARE( layer->featureCount(), 0L ); @@ -1854,13 +1855,14 @@ void TestQgsProcessing::createFeatureSink() destination = QStringLiteral( "memory:mylayer" ); QgsFields fields; fields.append( QgsField( QStringLiteral( "my_field" ), QVariant::String, QString(), 100 ) ); - sink.reset( QgsProcessingUtils::createFeatureSink( destination, context, fields, QgsWkbTypes::PointZM, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ) ) ); + sink.reset( QgsProcessingUtils::createFeatureSink( destination, context, fields, QgsWkbTypes::PointZM, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), QVariantMap(), QStringList(), QStringList(), QgsFeatureSink::RegeneratePrimaryKey ) ); QVERIFY( sink.get() ); layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, false ) ); QVERIFY( layer ); QCOMPARE( static_cast< QgsProxyFeatureSink *>( sink.get() )->destinationSink(), layer->dataProvider() ); QCOMPARE( layer->dataProvider()->name(), QStringLiteral( "memory" ) ); QCOMPARE( layer->name(), QStringLiteral( "mylayer" ) ); + QVERIFY( layer->customProperty( QStringLiteral( "OnConvertFormatRegeneratePrimaryKey" ) ).toBool() ); QCOMPARE( layer->wkbType(), QgsWkbTypes::PointZM ); QCOMPARE( layer->crs().authid(), QStringLiteral( "EPSG:3111" ) ); QCOMPARE( layer->fields().size(), 1 );