Skip to content
Permalink
Browse files

Merge pull request #36040 from espinafre/postgresql_fix_bigint_field_…

…attributes

Correctly handle bigint PostgreSQL values
  • Loading branch information
m-kuhn committed Apr 28, 2020
2 parents 35576d7 + 678b5a8 commit 232cf06cb60171bd5e07a7629a8e5ee501533a42
@@ -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() );
@@ -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" ) );
@@ -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")
@@ -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)
);

0 comments on commit 232cf06

Please sign in to comment.
You can’t perform that action at this time.