Skip to content

Commit 1fea20d

Browse files
committed
Split handling of literal default values from provider side
default value SQL clauses QgsVectorDataProvider now has two methods: - defaultValueClause: returns SQL fragment which must be evaluated by the provider to obtain the default value, eg sequence values - defaultValue: returns the literal constant default value for a field
1 parent 59b10d6 commit 1fea20d

17 files changed

+87
-40
lines changed

python/core/qgsvectordataprovider.sip

+13-2
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,20 @@ class QgsVectorDataProvider : QgsDataProvider
226226
const QMap<qint64, QgsGeometry> &geometry_map );
227227

228228
/**
229-
* Returns the default value for field specified by @c fieldId
229+
* Returns any literal default values which are present at the provider for a specified
230+
* field index.
231+
* @see defaultValueClause()
232+
*/
233+
virtual QVariant defaultValue( int fieldIndex ) const;
234+
235+
/**
236+
* Returns any default value clauses which are present at the provider for a specified
237+
* field index. These clauses are usually SQL fragments which must be evaluated by the
238+
* provider, eg sequence values.
239+
* @see defaultValue()
240+
* @note added in QGIS 3.0
230241
*/
231-
virtual QVariant defaultValue( int fieldId ) const;
242+
virtual QString defaultValueClause( int fieldIndex ) const;
232243

233244
/**
234245
* Returns any constraints which are present at the provider for a specified

src/app/qgisapp.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -6988,7 +6988,7 @@ void QgisApp::mergeAttributesOfSelectedFeatures()
69886988
QgsField fld( vl->fields().at( i ) );
69896989
bool isDefaultValue = vl->fields().fieldOrigin( i ) == QgsFields::OriginProvider &&
69906990
vl->dataProvider() &&
6991-
vl->dataProvider()->defaultValue( vl->fields().fieldOriginIndex( i ) ) == val;
6991+
vl->dataProvider()->defaultValueClause( vl->fields().fieldOriginIndex( i ) ) == val;
69926992

69936993
// convert to destination data type
69946994
if ( !isDefaultValue && !fld.convertCompatible( val ) )
@@ -7167,7 +7167,7 @@ void QgisApp::mergeSelectedFeatures()
71677167
QVariant val = attrs.at( i );
71687168
bool isDefaultValue = vl->fields().fieldOrigin( i ) == QgsFields::OriginProvider &&
71697169
vl->dataProvider() &&
7170-
vl->dataProvider()->defaultValue( vl->fields().fieldOriginIndex( i ) ) == val;
7170+
vl->dataProvider()->defaultValueClause( vl->fields().fieldOriginIndex( i ) ) == val;
71717171

71727172
// convert to destination data type
71737173
if ( !isDefaultValue && !vl->fields().at( i ).convertCompatible( val ) )
@@ -7481,7 +7481,7 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
74817481
}
74827482
else
74837483
{
7484-
defVal = pasteVectorLayer->dataProvider()->defaultValue( dst );
7484+
defVal = pasteVectorLayer->dataProvider()->defaultValueClause( dst );
74857485
}
74867486

74877487
if ( defVal.isValid() && !defVal.isNull() )

src/app/qgsfeatureaction.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ bool QgsFeatureAction::addFeature( const QgsAttributeMap& defaultAttributes, boo
176176
}
177177
else
178178
{
179-
v = provider->defaultValue( idx );
179+
v = provider->defaultValueClause( idx );
180180
}
181181

182182
mFeature->setAttribute( idx, v );

src/app/qgsidentifyresultsdialog.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
489489

490490
QString defVal;
491491
if ( fields.fieldOrigin( i ) == QgsFields::OriginProvider && vlayer->dataProvider() )
492-
defVal = vlayer->dataProvider()->defaultValue( fields.fieldOriginIndex( i ) ).toString();
492+
defVal = vlayer->dataProvider()->defaultValueClause( fields.fieldOriginIndex( i ) );
493493

494494
QString value = defVal == attrs.at( i ) ? defVal : fields.at( i ).displayString( attrs.at( i ) );
495495
QgsTreeWidgetItem *attrItem = new QgsTreeWidgetItem( QStringList() << QString::number( i ) << value );

src/app/qgsmergeattributesdialog.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ QgsAttributes QgsMergeAttributesDialog::mergedAttributes() const
540540
if ( !mVectorLayer->defaultValueExpression( fieldIdx ).isEmpty() )
541541
results[fieldIdx] = mVectorLayer->defaultValue( fieldIdx, mFeatureList.at( 0 ), &context );
542542
else if ( mVectorLayer->dataProvider() )
543-
results[fieldIdx] = mVectorLayer->dataProvider()->defaultValue( fieldIdx );
543+
results[fieldIdx] = mVectorLayer->dataProvider()->defaultValueClause( fieldIdx );
544544
else
545545
results[fieldIdx] = QVariant();
546546
continue;
@@ -567,7 +567,7 @@ QgsAttributes QgsMergeAttributesDialog::mergedAttributes() const
567567
}
568568
else if ( mVectorLayer->dataProvider() )
569569
{
570-
results[fieldIdx] = mVectorLayer->dataProvider()->defaultValue( fieldIdx );
570+
results[fieldIdx] = mVectorLayer->dataProvider()->defaultValueClause( fieldIdx );
571571
}
572572
widgetIndex++;
573573
}

src/core/qgsofflineediting.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ void QgsOfflineEditing::applyFeaturesAdded( QgsVectorLayer* offlineLayer, QgsVec
793793
if ( !remoteLayer->defaultValueExpression( k ).isEmpty() )
794794
newAttrs[k] = remoteLayer->defaultValue( k, f, &context );
795795
else if ( remoteFlds.fieldOrigin( k ) == QgsFields::OriginProvider )
796-
newAttrs[k] = remoteLayer->dataProvider()->defaultValue( remoteFlds.fieldOriginIndex( k ) );
796+
newAttrs[k] = remoteLayer->dataProvider()->defaultValueClause( remoteFlds.fieldOriginIndex( k ) );
797797
}
798798

799799
f.setAttributes( newAttrs );

src/core/qgsvectordataprovider.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ QVariant QgsVectorDataProvider::defaultValue( int fieldId ) const
9898
return QVariant();
9999
}
100100

101+
QString QgsVectorDataProvider::defaultValueClause( int fieldIndex ) const
102+
{
103+
Q_UNUSED( fieldIndex );
104+
return QString();
105+
}
106+
101107
QgsFieldConstraints::Constraints QgsVectorDataProvider::fieldConstraints( int fieldIndex ) const
102108
{
103109
QgsFields f = fields();

src/core/qgsvectordataprovider.h

+13-2
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,20 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
277277
const QgsGeometryMap &geometry_map );
278278

279279
/**
280-
* Returns the default value for field specified by @c fieldId
280+
* Returns any literal default values which are present at the provider for a specified
281+
* field index.
282+
* @see defaultValueClause()
283+
*/
284+
virtual QVariant defaultValue( int fieldIndex ) const;
285+
286+
/**
287+
* Returns any default value clauses which are present at the provider for a specified
288+
* field index. These clauses are usually SQL fragments which must be evaluated by the
289+
* provider, eg sequence values.
290+
* @see defaultValue()
291+
* @note added in QGIS 3.0
281292
*/
282-
virtual QVariant defaultValue( int fieldId ) const;
293+
virtual QString defaultValueClause( int fieldIndex ) const;
283294

284295
/**
285296
* Returns any constraints which are present at the provider for a specified

src/core/qgsvectorlayereditutils.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ int QgsVectorLayerEditUtils::splitFeatures( const QList<QgsPoint>& splitLine, bo
381381
QgsAttributes newAttributes = feat.attributes();
382382
Q_FOREACH ( int pkIdx, L->dataProvider()->pkAttributeIndexes() )
383383
{
384-
const QVariant defaultValue = L->dataProvider()->defaultValue( pkIdx );
384+
const QVariant defaultValue = L->dataProvider()->defaultValueClause( pkIdx );
385385
if ( !defaultValue.isNull() )
386386
{
387387
newAttributes[ pkIdx ] = defaultValue;

src/gui/editorwidgets/core/qgseditorwidgetfactory.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ QString QgsEditorWidgetFactory::representValue( QgsVectorLayer* vl, int fieldIdx
7070

7171
QString defVal;
7272
if ( vl->fields().fieldOrigin( fieldIdx ) == QgsFields::OriginProvider && vl->dataProvider() )
73-
defVal = vl->dataProvider()->defaultValue( vl->fields().fieldOriginIndex( fieldIdx ) ).toString();
73+
defVal = vl->dataProvider()->defaultValueClause( vl->fields().fieldOriginIndex( fieldIdx ) );
7474

7575
return value == defVal ? defVal : vl->fields().at( fieldIdx ).displayString( value );
7676
}

src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ QgsField QgsEditorWidgetWrapper::field() const
4444

4545
QVariant QgsEditorWidgetWrapper::defaultValue() const
4646
{
47-
mDefaultValue = layer()->dataProvider()->defaultValue( mFieldIdx );
47+
mDefaultValue = layer()->dataProvider()->defaultValueClause( mFieldIdx );
4848

4949
return mDefaultValue;
5050
}

src/providers/mssql/qgsmssqlprovider.cpp

+5-8
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ void QgsMssqlProvider::loadFields()
433433

434434
if ( !query.value( 12 ).isNull() )
435435
{
436-
mDefaultValues.insert( i, query.value( 12 ) );
436+
mDefaultValues.insert( i, query.value( 12 ).toString() );
437437
}
438438
++i;
439439
}
@@ -501,12 +501,9 @@ QString QgsMssqlProvider::quotedValue( const QVariant& value )
501501
}
502502
}
503503

504-
QVariant QgsMssqlProvider::defaultValue( int fieldId ) const
504+
QString QgsMssqlProvider::defaultValueClause( int fieldId ) const
505505
{
506-
if ( mDefaultValues.contains( fieldId ) )
507-
return mDefaultValues[fieldId];
508-
else
509-
return QVariant( QString::null );
506+
return mDefaultValues.value( fieldId, QString() );
510507
}
511508

512509
QString QgsMssqlProvider::storageType() const
@@ -815,7 +812,7 @@ bool QgsMssqlProvider::addFeatures( QgsFeatureList & flist )
815812
if ( fld.name().isEmpty() )
816813
continue; // invalid
817814

818-
if ( mDefaultValues.contains( i ) && mDefaultValues[i] == attrs.at( i ) )
815+
if ( mDefaultValues.contains( i ) && mDefaultValues.value( i ) == attrs.at( i ).toString() )
819816
continue; // skip fields having default values
820817

821818
if ( !first )
@@ -886,7 +883,7 @@ bool QgsMssqlProvider::addFeatures( QgsFeatureList & flist )
886883
if ( fld.name().isEmpty() )
887884
continue; // invalid
888885

889-
if ( mDefaultValues.contains( i ) && mDefaultValues[i] == attrs.at( i ) )
886+
if ( mDefaultValues.contains( i ) && mDefaultValues.value( i ) == attrs.at( i ).toString() )
890887
continue; // skip fields having default values
891888

892889
QVariant::Type type = fld.type();

src/providers/mssql/qgsmssqlprovider.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ class QgsMssqlProvider : public QgsVectorDataProvider
186186
//! Convert values to quoted values for database work *
187187
static QString quotedValue( const QVariant& value );
188188

189-
QVariant defaultValue( int fieldId ) const override;
189+
QString defaultValueClause( int fieldId ) const override;
190190

191191
//! Import a vector layer into the database
192192
static QgsVectorLayerImport::ImportError createEmptyLayer(
@@ -212,7 +212,7 @@ class QgsMssqlProvider : public QgsVectorDataProvider
212212

213213
//! Fields
214214
QgsFields mAttributeFields;
215-
QMap<int, QVariant> mDefaultValues;
215+
QMap<int, QString> mDefaultValues;
216216

217217
mutable QgsMssqlGeometryParser mParser;
218218

src/providers/postgres/qgspostgresprovider.cpp

+18-6
Original file line numberDiff line numberDiff line change
@@ -1716,15 +1716,27 @@ bool QgsPostgresProvider::isValid() const
17161716
return mValid;
17171717
}
17181718

1719+
QString QgsPostgresProvider::defaultValueClause( int fieldId ) const
1720+
{
1721+
QString defVal = mDefaultValues.value( fieldId, QString() );
1722+
1723+
if ( !providerProperty( EvaluateDefaultValues, false ).toBool() && !defVal.isEmpty() )
1724+
{
1725+
return defVal;
1726+
}
1727+
1728+
return QString();
1729+
}
1730+
17191731
QVariant QgsPostgresProvider::defaultValue( int fieldId ) const
17201732
{
1721-
QVariant defVal = mDefaultValues.value( fieldId, QString::null );
1733+
QString defVal = mDefaultValues.value( fieldId, QString() );
17221734

1723-
if ( providerProperty( EvaluateDefaultValues, false ).toBool() && !defVal.isNull() )
1735+
if ( providerProperty( EvaluateDefaultValues, false ).toBool() && !defVal.isEmpty() )
17241736
{
17251737
QgsField fld = field( fieldId );
17261738

1727-
QgsPostgresResult res( connectionRO()->PQexec( QStringLiteral( "SELECT %1" ).arg( defVal.toString() ) ) );
1739+
QgsPostgresResult res( connectionRO()->PQexec( QStringLiteral( "SELECT %1" ).arg( defVal ) ) );
17281740

17291741
if ( res.result() )
17301742
return convertValue( fld.type(), fld.subType(), res.PQgetvalue( 0, 0 ) );
@@ -1735,7 +1747,7 @@ QVariant QgsPostgresProvider::defaultValue( int fieldId ) const
17351747
}
17361748
}
17371749

1738-
return defVal;
1750+
return QVariant();
17391751
}
17401752

17411753
QString QgsPostgresProvider::paramValue( const QString& fieldValue, const QString &defaultValue ) const
@@ -1891,7 +1903,7 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
18911903
values += delim + QStringLiteral( "$%1" ).arg( defaultValues.size() + offset );
18921904
delim = ',';
18931905
fieldId << idx;
1894-
defaultValues << defaultValue( idx ).toString();
1906+
defaultValues << defaultValueClause( idx );
18951907
}
18961908
}
18971909

@@ -1928,7 +1940,7 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
19281940

19291941
insert += delim + quotedIdentifier( fieldname );
19301942

1931-
QString defVal = defaultValue( idx ).toString();
1943+
QString defVal = defaultValueClause( idx );
19321944

19331945
if ( i == flist.size() )
19341946
{

src/providers/postgres/qgspostgresprovider.h

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class QgsPostgresProvider : public QgsVectorDataProvider
160160
virtual bool isSaveAndLoadStyleToDBSupported() const override { return true; }
161161
QgsAttributeList attributeIndexes() const override;
162162
QgsAttributeList pkAttributeIndexes() const override { return mPrimaryKeyAttrs; }
163+
QString defaultValueClause( int fieldId ) const override;
163164
QVariant defaultValue( int fieldId ) const override;
164165

165166
/** Adds a list of features

tests/src/python/test_provider_postgres.py

+16-7
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
QgsTransactionGroup,
2929
QgsField,
3030
QgsFieldConstraints,
31+
QgsDataProvider,
3132
NULL
3233
)
3334
from qgis.gui import QgsEditorWidgetRegistry
@@ -84,9 +85,17 @@ def partiallyCompiledFilters(self):
8485

8586
# HERE GO THE PROVIDER SPECIFIC TESTS
8687
def testDefaultValue(self):
87-
self.assertEqual(self.provider.defaultValue(0), 'nextval(\'qgis_test."someData_pk_seq"\'::regclass)')
88+
self.provider.setProviderProperty(QgsDataProvider.EvaluateDefaultValues, True)
89+
self.assertTrue(isinstance(self.provider.defaultValue(0), int))
8890
self.assertEqual(self.provider.defaultValue(1), NULL)
89-
self.assertEqual(self.provider.defaultValue(2), '\'qgis\'::text')
91+
self.assertEqual(self.provider.defaultValue(2), 'qgis')
92+
self.provider.setProviderProperty(QgsDataProvider.EvaluateDefaultValues, False)
93+
94+
def testDefaultValueClause(self):
95+
self.provider.setProviderProperty(QgsDataProvider.EvaluateDefaultValues, False)
96+
self.assertEqual(self.provider.defaultValueClause(0), 'nextval(\'qgis_test."someData_pk_seq"\'::regclass)')
97+
self.assertFalse(self.provider.defaultValueClause(1))
98+
self.assertEqual(self.provider.defaultValueClause(2), '\'qgis\'::text')
9099

91100
def testDateTimeTypes(self):
92101
vl = QgsVectorLayer('%s table="qgis_test"."date_times" sql=' % (self.dbconn), "testdatetimes", "postgres")
@@ -248,7 +257,7 @@ def testPktMapInsert(self):
248257
vl = QgsVectorLayer('{} table="qgis_test"."{}" key="obj_id" sql='.format(self.dbconn, 'oid_serial_table'), "oid_serial", "postgres")
249258
self.assertTrue(vl.isValid())
250259
f = QgsFeature(vl.fields())
251-
f['obj_id'] = vl.dataProvider().defaultValue(0)
260+
f['obj_id'] = vl.dataProvider().defaultValueClause(0)
252261
f['name'] = 'Test'
253262
r, f = vl.dataProvider().addFeatures([f])
254263
self.assertTrue(r)
@@ -553,17 +562,17 @@ def testKey(lyr, key, kfnames):
553562
oflds = olyr.fields()
554563
if key is None:
555564
# if the pkey was not given, it will create a pkey
556-
self.assertEquals(oflds.size(), flds.size() + 1)
557-
self.assertEquals(oflds[0].name(), kfnames[0])
565+
self.assertEqual(oflds.size(), flds.size() + 1)
566+
self.assertEqual(oflds[0].name(), kfnames[0])
558567
for i in range(flds.size()):
559568
self.assertEqual(oflds[i + 1].name(), flds[i].name())
560569
else:
561570
# pkey was given, no extra field generated
562-
self.assertEquals(oflds.size(), flds.size())
571+
self.assertEqual(oflds.size(), flds.size())
563572
for i in range(oflds.size()):
564573
self.assertEqual(oflds[i].name(), flds[i].name())
565574
pks = olyr.pkAttributeList()
566-
self.assertEquals(len(pks), len(kfnames))
575+
self.assertEqual(len(pks), len(kfnames))
567576
for i in range(0, len(kfnames)):
568577
self.assertEqual(oflds[pks[i]].name(), kfnames[i])
569578

tests/src/python/test_qgsrelationeditwidget.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def test_link_feature(self):
153153
wrapper = self.createWrapper(self.vl_a, '"name"=\'Douglas Adams\'') # NOQA
154154

155155
f = QgsFeature(self.vl_b.fields())
156-
f.setAttributes([self.vl_b.dataProvider().defaultValue(0), 'The Hitchhiker\'s Guide to the Galaxy'])
156+
f.setAttributes([self.vl_b.dataProvider().defaultValueClause(0), 'The Hitchhiker\'s Guide to the Galaxy'])
157157
self.vl_b.addFeature(f)
158158

159159
def choose_linked_feature():
@@ -318,7 +318,7 @@ def addFeature(self, layer, defaultValues, defaultGeometry):
318318
if v:
319319
values.append(v)
320320
else:
321-
values.append(layer.dataProvider().defaultValue(i))
321+
values.append(layer.dataProvider().defaultValueClause(i))
322322
f = QgsFeature(layer.fields())
323323
f.setAttributes(self.values)
324324
f.setGeometry(defaultGeometry)

0 commit comments

Comments
 (0)