Skip to content

Commit

Permalink
createFeatures check unique constraints on unfiltered layer
Browse files Browse the repository at this point in the history
Fixes #30062
  • Loading branch information
elpaso committed Jun 5, 2019
1 parent 74d6b23 commit 12094db
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 2 deletions.
14 changes: 13 additions & 1 deletion src/core/qgsvectorlayerutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,19 @@ QgsFeatureList QgsVectorLayerUtils::createFeatures( const QgsVectorLayer *layer,

// Cache unique values
if ( hasUniqueConstraint && ! uniqueValueCaches.contains( idx ) )
uniqueValueCaches[ idx ] = layer->uniqueValues( idx );
{
// If the layer is filtered, get unique values from an unfiltered clone
if ( ! layer->subsetString().isEmpty() )
{
QgsVectorLayer *unfilteredClone { layer->clone( ) };
unfilteredClone->setSubsetString( QString( ) );
uniqueValueCaches[ idx ] = unfilteredClone->uniqueValues( idx );
}
else
{
uniqueValueCaches[ idx ] = layer->uniqueValues( idx );
}
}

// 2. client side default expression
// note - deliberately not using else if!
Expand Down
26 changes: 25 additions & 1 deletion tests/src/python/test_qgsvectorlayerutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

import os
import qgis # NOQA
import shutil
import tempfile

from qgis.PyQt.QtCore import QVariant
from qgis.core import (QgsProject,
Expand All @@ -32,7 +34,7 @@
NULL
)
from qgis.testing import start_app, unittest

from utilities import unitTestDataPath

start_app()

Expand Down Expand Up @@ -614,6 +616,28 @@ def test_create_nulls_and_defaults(self):
for f in features:
self.assertEqual(f.attributes()[0], 'my_default', f.id())

def test_unique_pk_when_subset(self):
"""Test unique values on filtered layer GH #30062"""

src = unitTestDataPath('points_gpkg.gpkg')
dest = tempfile.mktemp() + '.gpkg'
shutil.copy(src, dest)
vl = QgsVectorLayer(dest, 'vl', 'ogr')
self.assertTrue(vl.isValid())
features_data = []
it = vl.getFeatures()
for _ in range(3):
f = next(it)
features_data.append(QgsVectorLayerUtils.QgsFeatureData(f.geometry(), dict(zip(range(f.fields().count()), f.attributes()))))
# Set a filter
vl.setSubsetString('"fid" in (4,5,6)')
self.assertTrue(vl.isValid())
context = vl.createExpressionContext()
features = QgsVectorLayerUtils.createFeatures(vl, features_data, context)
self.assertTrue(vl.startEditing())
vl.addFeatures(features)
self.assertTrue(vl.commitChanges())


if __name__ == '__main__':
unittest.main()
Binary file modified tests/testdata/humanbeings.gpkg
Binary file not shown.
Binary file modified tests/testdata/points_gpkg.gpkg
Binary file not shown.

0 comments on commit 12094db

Please sign in to comment.