Skip to content

Commit 76667ee

Browse files
committed
check uniqueCheck before overwrite defaultValueClause
and some tests for it this fixes #20397 and fixes #20431 (cherry-picked from 32b7d7e)
1 parent 7eff348 commit 76667ee

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

src/core/qgsvectorlayerutils.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ QgsFeature QgsVectorLayerUtils::createFeature( const QgsVectorLayer *layer, cons
413413

414414
// 4. provider side default literal
415415
// note - deliberately not using else if!
416-
if ( ( !v.isValid() || ( fields.at( idx ).constraints().constraints() & QgsFieldConstraints::ConstraintUnique && QgsVectorLayerUtils::valueExists( layer, idx, v ) ) )
416+
if ( ( !v.isValid() || ( checkUnique && fields.at( idx ).constraints().constraints() & QgsFieldConstraints::ConstraintUnique && QgsVectorLayerUtils::valueExists( layer, idx, v ) ) )
417417
&& fields.fieldOrigin( idx ) == QgsFields::OriginProvider )
418418
{
419419
int providerIndex = fields.fieldOriginIndex( idx );

tests/src/python/test_qgsvectorlayerutils.py

+38
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# This will get replaced with a git SHA1 when you do a git archive
1313
__revision__ = '$Format:%H$'
1414

15+
import os
1516
import qgis # NOQA
1617

1718
from qgis.PyQt.QtCore import QVariant
@@ -297,6 +298,43 @@ def testCreateFeature(self):
297298
f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 132})
298299
self.assertEqual(f.attributes(), ['test_5', 132, NULL])
299300

301+
""" test creating a feature respecting unique values of postgres provider """
302+
layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddbl:double",
303+
"addfeat", "memory")
304+
305+
# init connection string
306+
dbconn = 'dbname=\'qgis_test\''
307+
if 'QGIS_PGTEST_DB' in os.environ:
308+
dbconn = os.environ['QGIS_PGTEST_DB']
309+
310+
# create a vector layer
311+
pg_layer = QgsVectorLayer('{} table="qgis_test"."authors" sql='.format(dbconn), "authors", "postgres")
312+
self.assertTrue(pg_layer.isValid())
313+
# check the default clause
314+
default_clause = 'nextval(\'qgis_test.authors_pk_seq\'::regclass)'
315+
self.assertEqual(pg_layer.dataProvider().defaultValueClause(0), default_clause)
316+
317+
# though default_clause is after the first create not unique (until save), it should fill up all the features with it
318+
pg_layer.startEditing()
319+
f = QgsVectorLayerUtils.createFeature(pg_layer)
320+
self.assertEqual(f.attributes(), [default_clause, NULL])
321+
self.assertTrue(pg_layer.addFeatures([f]))
322+
self.assertTrue(QgsVectorLayerUtils.valueExists(pg_layer, 0, default_clause))
323+
f = QgsVectorLayerUtils.createFeature(pg_layer)
324+
self.assertEqual(f.attributes(), [default_clause, NULL])
325+
self.assertTrue(pg_layer.addFeatures([f]))
326+
f = QgsVectorLayerUtils.createFeature(pg_layer)
327+
self.assertEqual(f.attributes(), [default_clause, NULL])
328+
self.assertTrue(pg_layer.addFeatures([f]))
329+
# if a unique value is passed, use it
330+
f = QgsVectorLayerUtils.createFeature(pg_layer, attributes={0: 40, 1: NULL})
331+
self.assertEqual(f.attributes(), [40, NULL])
332+
# and if a default value is configured use it as well
333+
pg_layer.setDefaultValueDefinition(0, QgsDefaultValue('11*4'))
334+
f = QgsVectorLayerUtils.createFeature(pg_layer)
335+
self.assertEqual(f.attributes(), [44, NULL])
336+
pg_layer.rollBack()
337+
300338
def testDuplicateFeature(self):
301339
""" test duplicating a feature """
302340

0 commit comments

Comments
 (0)