diff --git a/src/core/qgsvectorlayerutils.cpp b/src/core/qgsvectorlayerutils.cpp index a69fb4093a7e..67063ca6904f 100644 --- a/src/core/qgsvectorlayerutils.cpp +++ b/src/core/qgsvectorlayerutils.cpp @@ -413,7 +413,7 @@ QgsFeature QgsVectorLayerUtils::createFeature( const QgsVectorLayer *layer, cons // 4. provider side default literal // note - deliberately not using else if! - if ( ( !v.isValid() || ( fields.at( idx ).constraints().constraints() & QgsFieldConstraints::ConstraintUnique && QgsVectorLayerUtils::valueExists( layer, idx, v ) ) ) + if ( ( !v.isValid() || ( checkUnique && fields.at( idx ).constraints().constraints() & QgsFieldConstraints::ConstraintUnique && QgsVectorLayerUtils::valueExists( layer, idx, v ) ) ) && fields.fieldOrigin( idx ) == QgsFields::OriginProvider ) { int providerIndex = fields.fieldOriginIndex( idx ); diff --git a/tests/src/python/test_qgsvectorlayerutils.py b/tests/src/python/test_qgsvectorlayerutils.py index 492493bfc5a7..d21a2793e3b2 100644 --- a/tests/src/python/test_qgsvectorlayerutils.py +++ b/tests/src/python/test_qgsvectorlayerutils.py @@ -12,6 +12,7 @@ # This will get replaced with a git SHA1 when you do a git archive __revision__ = '$Format:%H$' +import os import qgis # NOQA from qgis.PyQt.QtCore import QVariant @@ -297,6 +298,43 @@ def testCreateFeature(self): f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 132}) self.assertEqual(f.attributes(), ['test_5', 132, NULL]) + """ test creating a feature respecting unique values of postgres provider """ + layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddbl:double", + "addfeat", "memory") + + # init connection string + dbconn = 'dbname=\'qgis_test\'' + if 'QGIS_PGTEST_DB' in os.environ: + dbconn = os.environ['QGIS_PGTEST_DB'] + + # create a vector layer + pg_layer = QgsVectorLayer('{} table="qgis_test"."authors" sql='.format(dbconn), "authors", "postgres") + self.assertTrue(pg_layer.isValid()) + # check the default clause + default_clause = 'nextval(\'qgis_test.authors_pk_seq\'::regclass)' + self.assertEqual(pg_layer.dataProvider().defaultValueClause(0), default_clause) + + # though default_clause is after the first create not unique (until save), it should fill up all the features with it + pg_layer.startEditing() + f = QgsVectorLayerUtils.createFeature(pg_layer) + self.assertEqual(f.attributes(), [default_clause, NULL]) + self.assertTrue(pg_layer.addFeatures([f])) + self.assertTrue(QgsVectorLayerUtils.valueExists(pg_layer, 0, default_clause)) + f = QgsVectorLayerUtils.createFeature(pg_layer) + self.assertEqual(f.attributes(), [default_clause, NULL]) + self.assertTrue(pg_layer.addFeatures([f])) + f = QgsVectorLayerUtils.createFeature(pg_layer) + self.assertEqual(f.attributes(), [default_clause, NULL]) + self.assertTrue(pg_layer.addFeatures([f])) + # if a unique value is passed, use it + f = QgsVectorLayerUtils.createFeature(pg_layer, attributes={0: 40, 1: NULL}) + self.assertEqual(f.attributes(), [40, NULL]) + # and if a default value is configured use it as well + pg_layer.setDefaultValueDefinition(0, QgsDefaultValue('11*4')) + f = QgsVectorLayerUtils.createFeature(pg_layer) + self.assertEqual(f.attributes(), [44, NULL]) + pg_layer.rollBack() + def testDuplicateFeature(self): """ test duplicating a feature """