Skip to content

Commit 92dda42

Browse files
committed
Do not loose signed semantic on converting int32 pk to fid
Fixes again editing of features with negative identifiers. Now a test fails, but it is the test being broken this time (testSignedIdentifiers). The test was added as part of 2bd7f44, which fixed a crash when using signed identifiers.
1 parent f4a135b commit 92dda42

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

src/providers/postgres/qgspostgresfeatureiterator.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,10 @@ bool QgsPostgresFeatureIterator::getFeature( QgsPostgresResult &queryResult, int
718718
case pktInt:
719719
case pktUint64:
720720
fid = mConn->getBinaryInt( queryResult, row, col++ );
721+
if ( mSource->mPrimaryKeyType == pktInt )
722+
{
723+
fid = QgsPostgresUtils::int32pk_to_fid( fid );
724+
}
721725
if ( !subsetOfAttributes || fetchAttributes.contains( mSource->mPrimaryKeyAttrs.at( 0 ) ) )
722726
{
723727
feature.setAttribute( mSource->mPrimaryKeyAttrs[0], fid );

src/providers/postgres/qgspostgresprovider.cpp

+3-6
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,14 @@
4242
const QString POSTGRES_KEY = "postgres";
4343
const QString POSTGRES_DESCRIPTION = "PostgreSQL/PostGIS data provider";
4444

45-
// We convert signed 32bit integers to unsigned 64bit integers
46-
// to support the whole range of int32 values (including negative)
47-
// See http://hub.qgis.org/issues/14262
48-
inline uint64_t PKINT2FID( int32_t x )
45+
inline int64_t PKINT2FID( int32_t x )
4946
{
50-
return static_cast<uint64_t>( x );
47+
return QgsPostgresUtils::int32pk_to_fid( x );
5148
}
5249

5350
inline int32_t FID2PKINT( int64_t x )
5451
{
55-
return static_cast<int32_t>( x );
52+
return QgsPostgresUtils::fid_to_int32pk( x );
5653
}
5754

5855

src/providers/postgres/qgspostgresprovider.h

+15
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,21 @@ class QgsPostgresUtils
502502
QSharedPointer<QgsPostgresSharedData> sharedData );
503503

504504
static QString andWhereClauses( const QString& c1, const QString& c2 );
505+
506+
static const int64_t int32pk_offset = 4294967296;
507+
508+
// We shift negative 32bit integers to above the max 32bit
509+
// positive integer to support the whole range of int32 values
510+
// See http://hub.qgis.org/issues/14262
511+
static int64_t int32pk_to_fid( int32_t x )
512+
{
513+
return x >= 0 ? x : x + int32pk_offset;
514+
}
515+
516+
static int32_t fid_to_int32pk( int64_t x )
517+
{
518+
return x <= (( int32pk_offset ) / 2.0 ) ? x : -( int32pk_offset - x );
519+
}
505520
};
506521

507522
/** Data shared between provider class and its feature sources. Ideally there should

0 commit comments

Comments
 (0)