@@ -271,6 +271,7 @@ QgsVectorLayerImport::ImportError QgsOgrProvider::createEmptyLayer(
271271
272272QgsOgrProvider::QgsOgrProvider( QString const & uri )
273273 : QgsVectorDataProvider( uri )
274+ , mFirstFieldIsFid( false )
274275 , ogrDataSource( nullptr )
275276 , mExtent( nullptr )
276277 , ogrLayer( nullptr )
@@ -733,6 +734,21 @@ void QgsOgrProvider::loadFields()
733734 OGRFeatureDefnH fdef = OGR_L_GetLayerDefn ( ogrLayer );
734735 if ( fdef )
735736 {
737+ // Expose the OGR FID if it comes from a "real" column (typically GPKG)
738+ // and make sure that this FID column is not exposed as a regular OGR field (shouldn't happen normally)
739+ mFirstFieldIsFid = !( EQUAL ( OGR_L_GetFIDColumn ( ogrLayer ), " " ) ) &&
740+ OGR_FD_GetFieldIndex ( fdef, OGR_L_GetFIDColumn ( ogrLayer ) ) < 0 ;
741+ if ( mFirstFieldIsFid )
742+ {
743+ mAttributeFields .append (
744+ QgsField (
745+ OGR_L_GetFIDColumn ( ogrLayer ),
746+ QVariant::LongLong,
747+ " Integer64"
748+ )
749+ );
750+ }
751+
736752 for ( int i = 0 ; i < OGR_FD_GetFieldCount ( fdef ); ++i )
737753 {
738754 OGRFieldDefnH fldDef = OGR_FD_GetFieldDefn ( fdef, i );
@@ -817,23 +833,23 @@ QString QgsOgrProvider::storageType() const
817833
818834void QgsOgrProvider::setRelevantFields ( OGRLayerH ogrLayer, bool fetchGeometry, const QgsAttributeList &fetchAttributes )
819835{
820- QgsOgrProviderUtils::setRelevantFields ( ogrLayer, mAttributeFields .count (), fetchGeometry, fetchAttributes );
836+ QgsOgrProviderUtils::setRelevantFields ( ogrLayer, mAttributeFields .count (), fetchGeometry, fetchAttributes, mFirstFieldIsFid );
821837}
822838
823839
824- void QgsOgrProviderUtils::setRelevantFields ( OGRLayerH ogrLayer, int fieldCount, bool fetchGeometry, const QgsAttributeList &fetchAttributes )
840+ void QgsOgrProviderUtils::setRelevantFields ( OGRLayerH ogrLayer, int fieldCount, bool fetchGeometry, const QgsAttributeList &fetchAttributes, bool firstAttrIsFid )
825841{
826842#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
827843 if ( OGR_L_TestCapability ( ogrLayer, OLCIgnoreFields ) )
828844 {
829845 QVector<const char *> ignoredFields;
830846 OGRFeatureDefnH featDefn = OGR_L_GetLayerDefn ( ogrLayer );
831- for ( int i = 0 ; i < fieldCount; i++ )
847+ for ( int i = ( firstAttrIsFid ? 1 : 0 ) ; i < fieldCount; i++ )
832848 {
833849 if ( !fetchAttributes.contains ( i ) )
834850 {
835851 // add to ignored fields
836- ignoredFields.append ( OGR_Fld_GetNameRef ( OGR_FD_GetFieldDefn ( featDefn, i ) ) );
852+ ignoredFields.append ( OGR_Fld_GetNameRef ( OGR_FD_GetFieldDefn ( featDefn, firstAttrIsFid ? i - 1 : i ) ) );
837853 }
838854 }
839855
@@ -1025,45 +1041,65 @@ bool QgsOgrProvider::addFeature( QgsFeature& f )
10251041
10261042 QgsLocaleNumC l;
10271043
1044+ int qgisAttId = ( mFirstFieldIsFid ) ? 1 : 0 ;
1045+ // If the first attribute is the FID and the user has set it, then use it
1046+ if ( mFirstFieldIsFid && attrs.count () > 0 )
1047+ {
1048+ QVariant attrFid = attrs.at ( 0 );
1049+ if ( !attrFid.isNull () )
1050+ {
1051+ bool ok = false ;
1052+ qlonglong id = attrFid.toLongLong ( &ok );
1053+ if ( ok )
1054+ {
1055+ #if GDAL_VERSION_MAJOR >= 2
1056+ OGR_F_SetFID ( feature, static_cast <GIntBig>( id ) );
1057+ #else
1058+ OGR_F_SetFID ( feature, static_cast <long >( id ) );
1059+ #endif
1060+ }
1061+ }
1062+ }
1063+
10281064 // add possible attribute information
1029- for ( int targetAttributeId = 0 ; targetAttributeId < attrs.count (); ++targetAttributeId )
1065+ for ( int ogrAttId = 0 ; qgisAttId < attrs.count (); ++qgisAttId, ++ogrAttId )
10301066 {
10311067 // don't try to set field from attribute map if it's not present in layer
1032- if ( targetAttributeId < 0 || targetAttributeId >= OGR_FD_GetFieldCount ( fdef ) )
1068+ if ( ogrAttId >= OGR_FD_GetFieldCount ( fdef ) )
10331069 continue ;
10341070
10351071 // if(!s.isEmpty())
10361072 // continue;
10371073 //
1038- OGRFieldDefnH fldDef = OGR_FD_GetFieldDefn ( fdef, targetAttributeId );
1074+ OGRFieldDefnH fldDef = OGR_FD_GetFieldDefn ( fdef, ogrAttId );
10391075 OGRFieldType type = OGR_Fld_GetType ( fldDef );
10401076
1041- QVariant attrVal = attrs.at ( targetAttributeId );
1077+ QVariant attrVal = attrs.at ( qgisAttId );
10421078 if ( attrVal.isNull () || ( type != OFTString && attrVal.toString ().isEmpty () ) )
10431079 {
1044- OGR_F_UnsetField ( feature, targetAttributeId );
1080+ OGR_F_UnsetField ( feature, ogrAttId );
10451081 }
10461082 else
10471083 {
10481084 switch ( type )
10491085 {
10501086 case OFTInteger:
1051- OGR_F_SetFieldInteger ( feature, targetAttributeId , attrVal.toInt () );
1087+ OGR_F_SetFieldInteger ( feature, ogrAttId , attrVal.toInt () );
10521088 break ;
10531089
10541090
10551091#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 2000000
10561092 case OFTInteger64:
1057- OGR_F_SetFieldInteger64 ( feature, targetAttributeId , attrVal.toLongLong () );
1093+ OGR_F_SetFieldInteger64 ( feature, ogrAttId , attrVal.toLongLong () );
10581094 break ;
10591095#endif
10601096
10611097 case OFTReal:
1062- OGR_F_SetFieldDouble ( feature, targetAttributeId , attrVal.toDouble () );
1098+ OGR_F_SetFieldDouble ( feature, ogrAttId , attrVal.toDouble () );
10631099 break ;
10641100
10651101 case OFTDate:
1066- OGR_F_SetFieldDateTime ( feature, targetAttributeId ,
1102+ OGR_F_SetFieldDateTime ( feature, ogrAttId ,
10671103 attrVal.toDate ().year (),
10681104 attrVal.toDate ().month (),
10691105 attrVal.toDate ().day (),
@@ -1072,7 +1108,7 @@ bool QgsOgrProvider::addFeature( QgsFeature& f )
10721108 break ;
10731109
10741110 case OFTTime:
1075- OGR_F_SetFieldDateTime ( feature, targetAttributeId ,
1111+ OGR_F_SetFieldDateTime ( feature, ogrAttId ,
10761112 0 , 0 , 0 ,
10771113 attrVal.toTime ().hour (),
10781114 attrVal.toTime ().minute (),
@@ -1081,7 +1117,7 @@ bool QgsOgrProvider::addFeature( QgsFeature& f )
10811117 break ;
10821118
10831119 case OFTDateTime:
1084- OGR_F_SetFieldDateTime ( feature, targetAttributeId ,
1120+ OGR_F_SetFieldDateTime ( feature, ogrAttId ,
10851121 attrVal.toDateTime ().date ().year (),
10861122 attrVal.toDateTime ().date ().month (),
10871123 attrVal.toDateTime ().date ().day (),
@@ -1093,14 +1129,14 @@ bool QgsOgrProvider::addFeature( QgsFeature& f )
10931129
10941130 case OFTString:
10951131 QgsDebugMsg ( QString ( " Writing string attribute %1 with %2, encoding %3" )
1096- .arg ( targetAttributeId )
1132+ .arg ( qgisAttId )
10971133 .arg ( attrVal.toString (),
10981134 mEncoding ->name ().data () ) );
1099- OGR_F_SetFieldString ( feature, targetAttributeId , mEncoding ->fromUnicode ( attrVal.toString () ).constData () );
1135+ OGR_F_SetFieldString ( feature, ogrAttId , mEncoding ->fromUnicode ( attrVal.toString () ).constData () );
11001136 break ;
11011137
11021138 default :
1103- QgsMessageLog::logMessage ( tr ( " type %1 for attribute %2 not found" ).arg ( type ).arg ( targetAttributeId ), tr ( " OGR" ) );
1139+ QgsMessageLog::logMessage ( tr ( " type %1 for attribute %2 not found" ).arg ( type ).arg ( qgisAttId ), tr ( " OGR" ) );
11041140 break ;
11051141 }
11061142 }
@@ -1113,9 +1149,16 @@ bool QgsOgrProvider::addFeature( QgsFeature& f )
11131149 }
11141150 else
11151151 {
1116- long id = OGR_F_GetFID ( feature );
1152+ QgsFeatureId id = static_cast <QgsFeatureId>( OGR_F_GetFID ( feature ) );
11171153 if ( id >= 0 )
1154+ {
11181155 f.setFeatureId ( id );
1156+
1157+ if ( mFirstFieldIsFid && attrs.count () > 0 )
1158+ {
1159+ f.setAttribute ( 0 , id );
1160+ }
1161+ }
11191162 }
11201163 OGR_F_Destroy ( feature );
11211164
@@ -1215,6 +1258,12 @@ bool QgsOgrProvider::deleteAttributes( const QgsAttributeIds &attributes )
12151258 qSort ( attrsLst.begin (), attrsLst.end (), qGreater<int >() );
12161259 Q_FOREACH ( int attr, attrsLst )
12171260 {
1261+ if ( attr == 0 && mFirstFieldIsFid )
1262+ {
1263+ pushError ( tr ( " Cannot delete feature id column" ) );
1264+ res = false ;
1265+ break ;
1266+ }
12181267 if ( OGR_L_DeleteField ( ogrLayer, attr ) != OGRERR_NONE )
12191268 {
12201269 pushError ( tr ( " OGR error deleting field %1: %2" ).arg ( attr ).arg ( CPLGetLastErrorMsg () ) );
@@ -1266,6 +1315,21 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
12661315 for ( QgsAttributeMap::const_iterator it2 = attr.begin (); it2 != attr.end (); ++it2 )
12671316 {
12681317 int f = it2.key ();
1318+ if ( mFirstFieldIsFid )
1319+ {
1320+ if ( f == 0 )
1321+ {
1322+ if ( it2->toLongLong () != fid )
1323+ {
1324+ pushError ( tr ( " Changing feature id of feature %1 is not allowed." ).arg ( fid ) );
1325+ continue ;
1326+ }
1327+ }
1328+ else
1329+ {
1330+ --f;
1331+ }
1332+ }
12691333
12701334 OGRFieldDefnH fd = OGR_F_GetFieldDefnRef ( of, f );
12711335 if ( !fd )
0 commit comments