wiki:rfc35_deletereorderalterfielddefn

Version 1 (modified by Even Rouault, 13 years ago) ( diff )

Add RFC35

RFC 35: Delete, reorder and alter field definitions of OGR layers

Authors: Even Rouault
Contact: even dot rouault at mines dash paris dot org
Status: Developement

Summary

This document proposes changes in OGR to add the capability to delete fields, reorder fields and alter field definitions, in OGR layer definitions.

Rationale

Currently, an OGR layer definition can only be altered to add a new field definition with OGRLayer::CreateField().

It is desirable to extend those capabilities to be able to delete, reorder and alter field definitions of existing layers. Such wish has been expressed in ticket #2671 and comes back regularly on QGIS mailing list (e.g. http://lists.osgeo.org/pipermail/qgis-user/2011-May/011935.html). QGIS currently has a "Table Manager" to work around the lack of DeleteField(), so a proper solution is clearly needed.

Planned Changes

The OGRLayer class will be extended with the following methods :

    virtual OGRErr      DeleteField( int iField );
    virtual OGRErr      ReorderField( int iOldFieldPos, int iNewFieldPos );
    virtual OGRErr      AlterFieldDefn( int iField, OGRFieldDefn* poNewFieldDefn, int nFlags );

The documentation of those new methods is :

/**
\fn OGRErr OGRLayer::DeleteField( int iField );

\brief Delete an existing field on a layer.

You must use this to delete existing fields
on a real layer. Internally the OGRFeatureDefn for the layer will be updated
to reflect the deleted field.  Applications should never modify the OGRFeatureDefn
used by a layer directly.

This function should not be called while there are feature objects in existance that
were obtained or created with the previous layer definition.

Not all drivers support this method. You can query a layer to check if it supports it
with the OLCDeleteField capability. Some drivers may only support this method while
there are still no features in the layer. When it is supported, the existings features of the
backing file/database should be updated accordingly.

This function is the same as the C function OGR_L_DeleteField().

@param iField index of the field to delete.

@return OGRERR_NONE on success.

@since OGR 1.9.0
*/

/**
\fn OGRErr OGRLayer::ReorderField( int iOldFieldPos, int iNewFieldPos );

\brief Reorder an existing field on a layer.

You must use this to reorder existing fields
on a real layer. Internally the OGRFeatureDefn for the layer will be updated
to reflect the reordering of the fields.  Applications should never modify the OGRFeatureDefn
used by a layer directly.

This function should not be called while there are feature objects in existance that
were obtained or created with the previous layer definition.

Not all drivers support this method. You can query a layer to check if it supports it
with the OLCReorderField capability. Some drivers may only support this method while
there are still no features in the layer. When it is supported, the existings features of the
backing file/database should be updated accordingly.

This function is the same as the C function OGR_L_ReorderField().

@param iOldFieldPos previous position of the field to move.
@param iNewFieldPos new position of the field to move.

@return OGRERR_NONE on success.

@since OGR 1.9.0
*/

/**
\fn OGRErr OGRLayer::AlterFieldDefn( int iField, OGRFieldDefn* poNewFieldDefn, int nFlags );

\brief Alter the definition of an existing field on a layer.

You must use this to alter the definition of an existing field of a real layer.
Internally the OGRFeatureDefn for the layer will be updated
to reflect the altered field.  Applications should never modify the OGRFeatureDefn
used by a layer directly.

This function should not be called while there are feature objects in existance that
were obtained or created with the previous layer definition.

Not all drivers support this method. You can query a layer to check if it supports it
with the OLCAlterFieldDefn capability. Some drivers may only support this method while
there are still no features in the layer. When it is supported, the existings features of the
backing file/database should be updated accordingly. Some drivers might also not support
all update flags.

This function is the same as the C function OGR_L_AlterFieldDefn().

@param iField index of the field whose definition must be altered.
@param poNewFieldDefn new field definition
@param nFlags combination of ALTER_NAME_FLAG, ALTER_TYPE_FLAG and ALTER_WIDTH_PRECISION_FLAG
to indicate which of the name and/or type and/or width and precision fields from the new field
definition must be taken into account.

@return OGRERR_NONE on success.

@since OGR 1.9.0
*/

Three new layer capabilities are added :

OLCDeleteField / "DeleteField": TRUE if this layer can delete
existing fields on the current layer using DeleteField(), otherwise FALSE.

OLCReorderField / "ReorderField": TRUE if this layer can reorder
existing fields on the current layer using ReorderField(), otherwise FALSE.

OLCAlterFieldDefn / "AlterFieldDefn": TRUE if this layer can alter
the definition of an existing field on the current layer using AlterFieldDefn(), otherwise FALSE.

The new methods are mapped to the C API :

OGRErr CPL_DLL OGR_L_DeleteField( OGRLayerH, int iField );
OGRErr CPL_DLL OGR_L_ReorderField( OGRLayerH, int iOldFieldPos, int iNewFieldPos );
OGRErr CPL_DLL OGR_L_AlterFieldDefn( OGRLayerH, int iField, OGRFieldDefnH hNewFieldDefn, int nFlags );

For the purpose of the implementation, new methods are also added to the OGRFeatureDefn class :

    OGRErr      DeleteFieldDefn( int iField );
    OGRErr      ReorderFieldDefn( int iOldFieldPos, int iNewFieldPos );

Compatibility Issues

None

Changed drivers

The shapefile driver will implement DeleteField(), ReorderField() and AlterFieldDefn(). Shapelib will be extended with DBFReorderField() and DBFAlterFieldDefn().

Note: The implementation of AlterFieldDefn() in the Shapefile driver does not currently support altering the field type, and will not reformat numeric values of existing features if width or precision are changed. However, appropriate field truncation or expansion will occur if the width is altered.

Other drivers, mainly database drivers (PG, MySQL, SQLite), could be easily extented to implement the new API by issuing the appropriate SQL command (DROP COLUMN, ALTER TABLE foo ALTER COLUMN bar, ...). The implementation of DeleteField() and AlterFieldDefn() in the PG driver is indeed planned, provided this RFC is adopted.

SWIG bindings

DeleteField(), ReorderField() and AlterFieldDefn() will be mapped to SWIG.

Test Suite

The autotest suite will be extended to test the implementation of the new API for the Shapefile driver. An example of the use of the new API is attached to ticket #2671 (rfc35_test.py) and will be turned into unit tests.

Implementation

Implementation will be done by Even Rouault in GDAL/OGR trunk. Changes in Shapelib will need to be pushed into upstream CVS by a Shapelib committer. The proposed implementation is attached as a patch in ticket #2671 (rfc35.patch).

Note: See TracWiki for help on using the wiki.