fix handling of null values for feature id in sqlite/postgis input - closes #1817
This commit is contained in:
parent
8c2d314413
commit
83eb8f2595
4 changed files with 58 additions and 1 deletions
|
@ -75,10 +75,17 @@ feature_ptr postgis_featureset::next()
|
||||||
|
|
||||||
if (key_field_)
|
if (key_field_)
|
||||||
{
|
{
|
||||||
|
std::string name = rs_->getFieldName(pos);
|
||||||
|
|
||||||
|
// null feature id is not acceptable
|
||||||
|
if (rs_->isNull(pos))
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_WARN(postgis) << "postgis_featureset: null value encountered for key_field: " << name;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// create feature with user driven id from attribute
|
// create feature with user driven id from attribute
|
||||||
int oid = rs_->getTypeOID(pos);
|
int oid = rs_->getTypeOID(pos);
|
||||||
const char* buf = rs_->getValue(pos);
|
const char* buf = rs_->getValue(pos);
|
||||||
std::string name = rs_->getFieldName(pos);
|
|
||||||
|
|
||||||
// validation happens of this type at initialization
|
// validation happens of this type at initialization
|
||||||
mapnik::value_integer val;
|
mapnik::value_integer val;
|
||||||
|
|
|
@ -71,6 +71,13 @@ feature_ptr sqlite_featureset::next()
|
||||||
return feature_ptr();
|
return feature_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// null feature id is not acceptable
|
||||||
|
if (rs_->column_type(1) == SQLITE_NULL)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_ERROR(postgis) << "sqlite_featureset: null value encountered for key_field";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
feature_ptr feature = feature_factory::create(ctx_,rs_->column_integer64(1));
|
feature_ptr feature = feature_factory::create(ctx_,rs_->column_integer64(1));
|
||||||
if (!geometry_utils::from_wkb(feature->paths(), data, size, format_))
|
if (!geometry_utils::from_wkb(feature->paths(), data, size, format_))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -626,6 +626,28 @@ if 'postgis' in mapnik.DatasourceCache.plugin_names() \
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
eq_(e.message != 'unidentifiable C++ exception', True)
|
eq_(e.message != 'unidentifiable C++ exception', True)
|
||||||
|
|
||||||
|
def test_null_id_field():
|
||||||
|
opts = {'type':'postgis',
|
||||||
|
'dbname':MAPNIK_TEST_DBNAME,
|
||||||
|
'geometry_field':'geom',
|
||||||
|
'table':"(select null::bigint as osm_id, GeomFromEWKT('SRID=4326;POINT(0 0)') as geom) as tmp"}
|
||||||
|
ds = mapnik.Datasource(**opts)
|
||||||
|
fs = ds.featureset()
|
||||||
|
feat = fs.next()
|
||||||
|
eq_(feat.id(),1L)
|
||||||
|
eq_(feat['osm_id'],None)
|
||||||
|
|
||||||
|
@raises(StopIteration)
|
||||||
|
def test_null_key_field():
|
||||||
|
opts = {'type':'postgis',
|
||||||
|
"key_field": 'osm_id',
|
||||||
|
'dbname':MAPNIK_TEST_DBNAME,
|
||||||
|
'geometry_field':'geom',
|
||||||
|
'table':"(select null::bigint as osm_id, GeomFromEWKT('SRID=4326;POINT(0 0)') as geom) as tmp"}
|
||||||
|
ds = mapnik.Datasource(**opts)
|
||||||
|
fs = ds.featureset()
|
||||||
|
feat = fs.next() ## should throw since key_field is null: StopIteration: No more features.
|
||||||
|
|
||||||
atexit.register(postgis_takedown)
|
atexit.register(postgis_takedown)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -379,6 +379,27 @@ if 'sqlite' in mapnik.DatasourceCache.plugin_names():
|
||||||
eq_(feat['OGC_FID'],2)
|
eq_(feat['OGC_FID'],2)
|
||||||
eq_(feat['bigint'],922337203685477580)
|
eq_(feat['bigint'],922337203685477580)
|
||||||
|
|
||||||
|
|
||||||
|
@raises(StopIteration)
|
||||||
|
def test_null_id_field():
|
||||||
|
# form up an in-memory test db
|
||||||
|
wkb = '010100000000000000000000000000000000000000'
|
||||||
|
# note: the osm_id should be declared INTEGER PRIMARY KEY
|
||||||
|
# but in this case we intentionally do not make this a valid pkey
|
||||||
|
# otherwise sqlite would turn the null into a valid, serial id
|
||||||
|
ds = mapnik.SQLite(file=':memory:',
|
||||||
|
table='test1',
|
||||||
|
initdb='''
|
||||||
|
create table test1 (osm_id INTEGER,geometry BLOB);
|
||||||
|
insert into test1 values (null,x'%s');
|
||||||
|
''' % wkb,
|
||||||
|
extent='-180,-60,180,60',
|
||||||
|
use_spatial_index=False,
|
||||||
|
key_field='osm_id'
|
||||||
|
)
|
||||||
|
fs = ds.featureset()
|
||||||
|
feat = fs.next() ## should throw since key_field is null: StopIteration: No more features.
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
setup()
|
setup()
|
||||||
[eval(run)() for run in dir() if 'test_' in run]
|
[eval(run)() for run in dir() if 'test_' in run]
|
||||||
|
|
Loading…
Reference in a new issue