Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
BUG: fix identity field management when adding a feature, fix #33681
(cherry picked from commit 0d5456f)
  • Loading branch information
speillet authored and nyalldawson committed Jun 19, 2020
1 parent 254fff0 commit c5bde16
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
64 changes: 61 additions & 3 deletions src/providers/oracle/qgsoracleprovider.cpp
Expand Up @@ -1182,7 +1182,43 @@ bool QgsOracleProvider::isValid() const

QVariant QgsOracleProvider::defaultValue( int fieldId ) const
{
return mDefaultValues.value( fieldId, QVariant() );
QString defVal = mDefaultValues.value( fieldId, QString() ).toString();

if ( providerProperty( EvaluateDefaultValues, false ).toBool() && !defVal.isEmpty() )
{
QgsField fld = field( fieldId );
return evaluateDefaultExpression( defVal, fld.type() );
}

return defVal;
}

QString QgsOracleProvider::defaultValueClause( int fieldId ) const
{
QString defVal = mDefaultValues.value( fieldId, QString() ).toString();

if ( !providerProperty( EvaluateDefaultValues, false ).toBool() && !defVal.isEmpty() )
{
return defVal;
}

return QString();
}


bool QgsOracleProvider::skipConstraintCheck( int fieldIndex, QgsFieldConstraints::Constraint constraint, const QVariant &value ) const
{
Q_UNUSED( constraint );
if ( providerProperty( EvaluateDefaultValues, false ).toBool() )
{
return !mDefaultValues.value( fieldIndex ).toString().isEmpty();
}
else
{
// stricter check - if we are evaluating default values only on commit then we can only bypass the check
// if the attribute values matches the original default clause
return mDefaultValues.value( fieldIndex ) == value.toString() && !value.isNull();
}
}

QVariant QgsOracleProvider::evaluateDefaultExpression( const QString &value, const QVariant::Type &fieldType ) const
Expand Down Expand Up @@ -1230,7 +1266,7 @@ bool QgsOracleProvider::addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flag

try
{
QSqlQuery ins( db ), getfid( db );
QSqlQuery ins( db ), getfid( db ), identitytype( db );

if ( !conn->begin( db ) )
{
Expand All @@ -1244,13 +1280,31 @@ bool QgsOracleProvider::addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flag

QStringList defaultValues;
QList<int> fieldId;
QList<int> alwaysGenerated;

if ( !mGeometryColumn.isNull() )
{
insert += quotedIdentifier( mGeometryColumn );
values += '?';
delim = ',';
}
QString sql = QStringLiteral( "SELECT a.column_name "
"FROM all_tab_identity_cols a "
"WHERE a.owner = '%1' "
"AND a.table_name = '%2' "
"AND a.generation_type = 'ALWAYS'" ).arg( mOwnerName ).arg( mTableName );
identitytype.prepare( sql );

if ( identitytype.exec() )
{
while ( identitytype.next() )
{
if ( flist[0].fields().names().contains( identitytype.value( 0 ).toString() ) )
{
alwaysGenerated.append( flist[0].fields().indexOf( identitytype.value( 0 ).toString() ) );
}
}
}

if ( mPrimaryKeyType == PktInt || mPrimaryKeyType == PktFidMap )
{
Expand All @@ -1260,8 +1314,10 @@ bool QgsOracleProvider::addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flag
for ( int idx : constMPrimaryKeyAttrs )
{
QgsField fld = field( idx );
insert += delim + quotedIdentifier( fld.name() );
keys += kdelim + quotedIdentifier( fld.name() );
if ( alwaysGenerated.contains( idx ) )
continue;
insert += delim + quotedIdentifier( fld.name() );
values += delim + '?';
delim = ',';
kdelim = ',';
Expand All @@ -1282,6 +1338,8 @@ bool QgsOracleProvider::addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flag
for ( int idx = 0; idx < std::min( attributevec.size(), mAttributeFields.size() ); ++idx )
{
QVariant v = attributevec[idx];
if ( alwaysGenerated.contains( idx ) )
continue;
if ( !v.isValid() )
continue;

Expand Down
2 changes: 2 additions & 0 deletions src/providers/oracle/qgsoracleprovider.h
Expand Up @@ -142,6 +142,8 @@ class QgsOracleProvider : public QgsVectorDataProvider
QgsAttributeList pkAttributeIndexes() const override { return mPrimaryKeyAttrs; }
QVariant defaultValue( QString fieldName, QString tableName = QString(), QString schemaName = QString() );
QVariant defaultValue( int fieldId ) const override;
QString defaultValueClause( int fieldId ) const override;
bool skipConstraintCheck( int fieldIndex, QgsFieldConstraints::Constraint constraint, const QVariant &value = QVariant() ) const override;
bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = nullptr ) override;
bool deleteFeatures( const QgsFeatureIds &id ) override;
bool addAttributes( const QList<QgsField> &attributes ) override;
Expand Down

0 comments on commit c5bde16

Please sign in to comment.