From 2daf6f0db476fd4216dbb17fa36642e06e6f8365 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 28 Apr 2020 16:52:46 +0000 Subject: [PATCH] Backport of PR #36063 (PgSQL bigint ordinary fields) (cherry picked from commit a113b5a1df028cac2308bddb34bcf93b1d3a29a3) --- .../postgres/qgspostgresfeatureiterator.cpp | 5 ++ .../postgres/qgspostgresprovider.cpp | 2 + tests/src/python/test_provider_postgres.py | 47 +++++++++++++++++++ .../provider/testdata_pg_bigint_pk.sql | 2 + 4 files changed, 56 insertions(+) diff --git a/src/providers/postgres/qgspostgresfeatureiterator.cpp b/src/providers/postgres/qgspostgresfeatureiterator.cpp index f5d3f86fee2e..faecefe86b13 100644 --- a/src/providers/postgres/qgspostgresfeatureiterator.cpp +++ b/src/providers/postgres/qgspostgresfeatureiterator.cpp @@ -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() ); diff --git a/src/providers/postgres/qgspostgresprovider.cpp b/src/providers/postgres/qgspostgresprovider.cpp index a1a4495c6a74..1db12d131d1b 100644 --- a/src/providers/postgres/qgspostgresprovider.cpp +++ b/src/providers/postgres/qgspostgresprovider.cpp @@ -2058,7 +2058,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" ) ); diff --git a/tests/src/python/test_provider_postgres.py b/tests/src/python/test_provider_postgres.py index 4b8169747e82..770fe3454c7b 100644 --- a/tests/src/python/test_provider_postgres.py +++ b/tests/src/python/test_provider_postgres.py @@ -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") diff --git a/tests/testdata/provider/testdata_pg_bigint_pk.sql b/tests/testdata/provider/testdata_pg_bigint_pk.sql index 3db260a2b8e8..5703d55e30f4 100644 --- a/tests/testdata/provider/testdata_pg_bigint_pk.sql +++ b/tests/testdata/provider/testdata_pg_bigint_pk.sql @@ -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) );