Skip to content

Commit

Permalink
Merge pull request #7144 from rouault/fix_18976
Browse files Browse the repository at this point in the history
[Postgres provider] Speed up feature insertion when pkid column is not set (fixes #18976)
  • Loading branch information
rouault committed Jun 2, 2018
2 parents 2ed200a + a9a8fbd commit 7e2ca8f
Showing 1 changed file with 35 additions and 7 deletions.
42 changes: 35 additions & 7 deletions src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -2029,15 +2029,41 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist, Flags flags )
delim = ',';
}

if ( mPrimaryKeyType == PktInt || mPrimaryKeyType == PktFidMap || mPrimaryKeyType == PktUint64 )
// Optimization: if we have a single primary key column whose default value
// is a sequence, and that none of the features have a value set for that
// column, then we can completely omit inserting it.
bool skipSinglePKField = false;

if ( ( mPrimaryKeyType == PktInt || mPrimaryKeyType == PktFidMap || mPrimaryKeyType == PktUint64 ) )
{
Q_FOREACH ( int idx, mPrimaryKeyAttrs )
if ( mPrimaryKeyAttrs.size() == 1 &&
defaultValueClause( mPrimaryKeyAttrs[0] ).startsWith( "nextval(" ) )
{
insert += delim + quotedIdentifier( field( idx ).name() );
values += delim + QStringLiteral( "$%1" ).arg( defaultValues.size() + offset );
delim = ',';
fieldId << idx;
defaultValues << defaultValueClause( idx );
bool foundNonNullPK = false;
int idx = mPrimaryKeyAttrs[0];
for ( int i = 0; i < flist.size(); i++ )
{
QgsAttributes attrs2 = flist[i].attributes();
QVariant v2 = attrs2.value( idx, QVariant( QVariant::Int ) );
if ( !v2.isNull() )
{
foundNonNullPK = true;
break;
}
}
skipSinglePKField = !foundNonNullPK;
}

if ( !skipSinglePKField )
{
for ( int idx : mPrimaryKeyAttrs )
{
insert += delim + quotedIdentifier( field( idx ).name() );
values += delim + QStringLiteral( "$%1" ).arg( defaultValues.size() + offset );
delim = ',';
fieldId << idx;
defaultValues << defaultValueClause( idx );
}
}
}

Expand All @@ -2048,6 +2074,8 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist, Flags flags )
for ( int idx = 0; idx < attributevec.count(); ++idx )
{
QVariant v = attributevec.value( idx, QVariant( QVariant::Int ) ); // default to NULL for missing attributes
if ( skipSinglePKField && idx == mPrimaryKeyAttrs[0] )
continue;
if ( fieldId.contains( idx ) )
continue;

Expand Down

0 comments on commit 7e2ca8f

Please sign in to comment.