RFC 67:OGR中的空值
作者:连鲁奥
联系人:even.rouault,网址:spatialys.com
状态:通过、实施
实现版本:2.2
总结
除了现有的未设置状态外,此RFC还实现了特征字段的空值概念。
理论基础
目前,OGR只支持一个概念来表示字段值丢失:unset字段的概念。
因此,假设具有2个特性的JSon特性集合的属性是{“foo”:“bar”}和{“foo”:“bar”,“other_field”:null},那么OGR当前返回other_field在这两种情况下都是未设置的。
这里提出的是,在第一个完全没有“other_field”关键字的情况下,我们使用当前的unset field概念。对于另一种情况,我们添加了一个新的空字段概念。
这两个概念之间的区别适用于所有基于GeoJSON的格式和协议,因此GeoJSON、ElasticSearch、MongoDB、CouchDB和Cloudant。
这也适用于GML,其中缺少元素的语义将映射到unset字段,而具有xsi:nil=“true”属性的元素将映射到空字段。
变化
OGRField
“原始字段”并集中的Set结构被修改为添加第三个标记
struct {
int nMarker1;
int nMarker2;
int nMarker3;
} Set;
这与这项工作没有严格的关系,但是第三个标记降低了真实值被误解为unset/null的可能性。这不会增加已经至少12字节大的结构的大小。
OGRUnsetMarker=-21121的当前特殊值将在3 markers for unset字段中设置(当前设置为前2个标记)。
类似地,对于新的空状态,新值OGRNullMarker=-21122将设置为3个标记。
OGRFeature
添加方法int IsFieldNull(int nFieldIdx)和void SetNullField(intnfieldidx)。
访问器GetFieldXXXX()被修改为考虑空值,就像它们在未设置的字段上被调用一样,因此对于数值字段类型返回0,对于字符串字段返回空字符串,对于日期时间字段返回FALSE,对于基于列表的类型返回空值。
添加了一个方便的方法OGRFeature::IsFieldSetAndNotNull(),以简化以前使用IsFieldSet()的现有代码的移植,并且不需要区分unset和null状态。
计算机辅助编程接口
将添加以下功能:
int CPL_DLL OGR_F_IsFieldNull( OGRFeatureH, int );
void CPL_DLL OGR_F_SetFieldNull( OGRFeatureH, int );
int CPL_DLL OGR_F_IsFieldSetAndNotNull( OGRFeatureH, int );
将添加较低级别的函数来直接操作原始字段联合(主要用于核心和少数驱动程序),而不是直接测试/设置标记:
int CPL_DLL OGR_RawField_IsUnset( OGRField* );
int CPL_DLL OGR_RawField_IsNull( OGRField* );
void CPL_DLL OGR_RawField_SetUnset( OGRField* );
void CPL_DLL OGR_RawField_SetNull( OGRField* );
SWIG绑定(Python/Java/C#/Perl)更改
新方法将映射到SWIG。
驱动程序
将修改以下驱动程序以将unset和NULL状态视为不同的状态:GeoJSON、ElasticSearch、MongoDB、CouchDB、Cloudant、GML、GML as、WFS。
注意:关于GMLAS驱动程序,当xxxx是可选的nillable XML元素时,默认情况下保留先前的行为,即同时具有xxxx和xxxxnil字段(可以通过gmlasconf.xml文件文件)。基本原理是GMLAS驱动程序主要用于转换为支持SQL的格式,这些格式无法区分unset和null状态,因此需要2个专用字段。
CSV驱动程序将被修改,以便在指定空字符串为空打开选项时,使用新的空状态。
所有在编写部分测试源特性是否有字段未设置的驱动程序也将测试该字段是否为空。
对于基于SQL的驱动程序(PG、PGDump、Carto、MySQL、OCI、SQLite、GPKG),在读取SQL空值时将映射到新的空状态。写入时,在相应的INSERT或UPDATE语句中不会提到未设置字段。而一个空字段将被提及并设置为空。在插入时,通常不会有行为上的差异,除非在字段上定义了默认值,在这种情况下,数据库引擎将使用该值来设置未设置的情况下的值。更新时,未设置的字段将看不到其内容被数据库更新,其中设置为NULL的字段将更新为NULL。
公用事业
没有直接更改,但由于OGRFeature::DumpReadable()方法被修改,因此不再显示未设置的功能字段,因此ogrinfo的输出将受到影响。
文档
所有新的方法/功能都记录在案。
测试套件
将测试核心更改和更新的驱动程序。
兼容性问题
在GDAL源代码中以及在调用外部代码时,当前使用OGRFeature::IsFieldSet()/OGRu Fu IsFieldSet()的所有代码也应更新为used IsFieldNull()/OGRu Fu IsFieldNull(),以便与未设置的情况完全相同,或者添加新的适当行为。添加了一个方便的方法和函数OGRFeature::IsFieldSetAndNotNull()/OGRu Fu IsFieldSetAndNotNull(),以简化现有代码的移植。
否则,现有代码将看到0表示数值字段类型,空字符串表示字符串字段,FALSE表示日期时间字段,空字符串表示基于列表的类型。
在写端,对于GeoJSON驱动程序,在GDAL 2.1或之前,未设置的字段被写为field_name:null。从GDAL 2.2开始,只有用OGR_F_SetFieldNull()显式设置为空的字段才会用空值写入。对应的JSon feature元素中不存在特性的未设置字段。
将更新MIGRATION_GUIDE.TXT以讨论这些兼容性问题。
实施
该实现将由Even Rouault(Spatialys)完成,并由Safe软件赞助。
投票历史
+1名来自朱卡尔、丹尼尔姆、霍华德和埃文