Skip to content

Commit

Permalink
Merge pull request #36063 from qgis-bot/backport-36040-to-release-3_12
Browse files Browse the repository at this point in the history
[Backport release-3_12] Correctly handle bigint PostgreSQL values
  • Loading branch information
m-kuhn committed Apr 29, 2020
2 parents 1f2374f + a113b5a commit 8146e75
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/providers/postgres/qgspostgresfeatureiterator.cpp
Expand Up @@ -857,6 +857,11 @@ void QgsPostgresFeatureIterator::getFeatureAttribute( int idx, QgsPostgresResult
}
break;
}
case QVariant::LongLong:
{
v = QgsPostgresProvider::convertValue( fld.type(), fld.subType(), QString::number( mConn->getBinaryInt( queryResult, row, col ) ), fld.typeName() );
break;
}
default:
{
v = QgsPostgresProvider::convertValue( fld.type(), fld.subType(), queryResult.PQgetvalue( row, col ), fld.typeName() );
Expand Down
2 changes: 2 additions & 0 deletions src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -2070,7 +2070,9 @@ QVariant QgsPostgresProvider::defaultValue( int fieldId ) const
QgsPostgresResult res( connectionRO()->PQexec( QStringLiteral( "SELECT %1" ).arg( defVal ) ) );

if ( res.result() )
{
return convertValue( fld.type(), fld.subType(), res.PQgetvalue( 0, 0 ), fld.typeName() );
}
else
{
pushError( tr( "Could not execute query" ) );
Expand Down
47 changes: 47 additions & 0 deletions tests/src/python/test_provider_postgres.py
Expand Up @@ -430,6 +430,53 @@ def testPktIntInsert(self):
self.assertNotEqual(f[0]['pk'], NULL, f[0].attributes())
vl.deleteFeatures([f[0].id()])

def testNonPkBigintField(self):
"""Test if we can correctly insert, read and change attributes(fields) of type bigint and which are not PKs."""
vl = QgsVectorLayer('{} sslmode=disable srid=4326 key="pk" table="qgis_test".{} (geom)'.format(self.dbconn, 'bigint_pk'), "bigint_pk", "postgres")
self.assertTrue(vl.isValid())
flds = vl.fields()

# check if default values are correctly read back
f = next(vl.getFeatures(QgsFeatureRequest()))
bigint_with_default_idx = vl.fields().lookupField('bigint_attribute_def')
self.assertEqual(f.attributes()[bigint_with_default_idx], 42)

# check if we can overwrite a default value
vl.startEditing()
vl.changeAttributeValue(f.id(), bigint_with_default_idx, 43)

pkidx = vl.fields().lookupField('pk')
editedid = f.attributes()[pkidx]

self.assertTrue(vl.commitChanges())
vl2 = QgsVectorLayer('{} sslmode=disable srid=4326 key="pk" table="qgis_test".{} (geom)'.format(self.dbconn, 'bigint_pk'), "bigint_pk", "postgres")
flds = vl2.fields()
self.assertTrue(vl2.isValid())
f = next(vl2.getFeatures(QgsFeatureRequest().setFilterExpression('pk = ' + str(editedid))))
bigint_with_default_idx = vl2.fields().lookupField('bigint_attribute_def')
self.assertEqual(f.attributes()[bigint_with_default_idx], 43)

# check if we can insert a new value
dp = vl2.dataProvider()
dp.setProviderProperty(QgsDataProvider.EvaluateDefaultValues, 1)
pkidx = vl2.fields().lookupField('pk')
vl2.startEditing()
f = QgsFeature(vl2.fields())
f['pk'] = NULL
f['value'] = 'The answer.'
f['bigint_attribute'] = 84
f.setAttribute(pkidx, vl2.dataProvider().defaultValue(pkidx))
f.setAttribute(bigint_with_default_idx, vl2.dataProvider().defaultValue(bigint_with_default_idx))
r, f = vl2.dataProvider().addFeatures([f])
self.assertTrue(r)
vl2.commitChanges()
inserted_id = f[0]['pk']

f = next(vl2.getFeatures(QgsFeatureRequest().setFilterExpression('pk = ' + str(inserted_id))))

self.assertEqual(f['bigint_attribute'], 84)
self.assertEqual(f['bigint_attribute_def'], 42)

def testPktUpdateBigintPk(self):
"""Test if we can update objects with positive, zero and negative bigint PKs."""
vl = QgsVectorLayer('{} sslmode=disable srid=4326 key="pk" table="qgis_test".{} (geom)'.format(self.dbconn, 'bigint_pk'), "bigint_pk", "postgres")
Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/provider/testdata_pg_bigint_pk.sql
Expand Up @@ -3,6 +3,8 @@ DROP TABLE IF EXISTS qgis_test.bigint_pk;
CREATE TABLE qgis_test.bigint_pk (
pk bigserial NOT NULL PRIMARY KEY,
value varchar(16),
bigint_attribute bigint,
bigint_attribute_def bigint DEFAULT 42,
geom geometry(Point, 4326)
);

Expand Down

0 comments on commit 8146e75

Please sign in to comment.