From 249c8dca20716ef0b20d02dba80b2a185725c4f1 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 14 Nov 2016 09:24:06 +1000 Subject: [PATCH] Prioritise provider default literals over reused values when creating a new feature --- src/core/qgsvectorlayerutils.cpp | 33 ++++++++------------ tests/src/python/test_provider_spatialite.py | 8 ++--- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/core/qgsvectorlayerutils.cpp b/src/core/qgsvectorlayerutils.cpp index eb54bfab874..64155b0b04a 100644 --- a/src/core/qgsvectorlayerutils.cpp +++ b/src/core/qgsvectorlayerutils.cpp @@ -27,18 +27,6 @@ bool QgsVectorLayerUtils::valueExists( const QgsVectorLayer* layer, int fieldInd if ( fieldIndex < 0 || fieldIndex >= fields.count() ) return false; - // check - if value is a provider side defaultValueClause then we exclude it from the check - if ( fields.fieldOrigin( fieldIndex ) == QgsFields::OriginProvider ) - { - int providerIdx = fields.fieldOriginIndex( fieldIndex ); - QString providerDefaultClause = layer->dataProvider()->defaultValueClause( providerIdx ); - if ( !providerDefaultClause.isEmpty() && value.toString() == providerDefaultClause ) - { - // exempt from check - return false; - } - } - QString fieldName = fields.at( fieldIndex ).name(); // build up an optimised feature request @@ -272,19 +260,24 @@ QgsFeature QgsVectorLayerUtils::createFeature( QgsVectorLayer* layer, const QgsG } } - // 3. passed attribute value - // note - deliberately not using else if! - if ( !v.isValid() && attributes.contains( idx ) ) - { - v = attributes.value( idx ); - } - - // 4. provider side default literal + // 3. provider side default literal // note - deliberately not using else if! if ( !v.isValid() && fields.fieldOrigin( idx ) == QgsFields::OriginProvider ) { int providerIndex = fields.fieldOriginIndex( idx ); v = layer->dataProvider()->defaultValue( providerIndex ); + if ( v.isValid() ) + { + //trust that the provider default has been sensibly set not to violate any constraints + checkUnique = false; + } + } + + // 4. passed attribute value + // note - deliberately not using else if! + if ( !v.isValid() && attributes.contains( idx ) ) + { + v = attributes.value( idx ); } // last of all... check that unique constraints are respected diff --git a/tests/src/python/test_provider_spatialite.py b/tests/src/python/test_provider_spatialite.py index 034ea3cf156..e5b722149f8 100644 --- a/tests/src/python/test_provider_spatialite.py +++ b/tests/src/python/test_provider_spatialite.py @@ -474,14 +474,14 @@ class TestQgsSpatialiteProvider(unittest.TestCase, ProviderTestCase): f = QgsVectorLayerUtils.createFeature(vl) self.assertEqual(f.attributes(), [None, "qgis 'is good", 5, 5.7, None]) - # check that provider passed attribute values take precedence over default literals + # check that provider default literals take precedence over passed attribute values f = QgsVectorLayerUtils.createFeature(vl, attributes={1: 'qgis is great', 0: 3}) - self.assertEqual(f.attributes(), [3, "qgis is great", 5, 5.7, None]) + self.assertEqual(f.attributes(), [3, "qgis 'is good", 5, 5.7, None]) - # test take vector layer default value expression overrides postgres provider default clause + # test that vector layer default value expression overrides provider default literal vl.setDefaultValueExpression(3, "4*3") f = QgsVectorLayerUtils.createFeature(vl, attributes={1: 'qgis is great', 0: 3}) - self.assertEqual(f.attributes(), [3, "qgis is great", 5, 12, None]) + self.assertEqual(f.attributes(), [3, "qgis 'is good", 5, 12, None]) if __name__ == '__main__': unittest.main()