Yes, that's indisputably true; let's go to directly check using
a reasonably sized dataset taken from the wild.
So I've started my test by loading the Italian Local Council
Boundaries from ISTAT:
http://www.istat.it/uploads/com2011.zipThis dataset contains about 8,100 MultiPolygons, but the vast
majority of Local Councils simply have one single Polygon.
Then I've created a further table just containing the Exterior
Ring (Linestring) for all single-Polygon Local Councils (they
are about 7,600):
CREATE TABLE com2 AS
SELECT nome_com, ST_ExteriorRing(geometry) AS geom
FROM com2011
WHERE ST_NumGeometries(geometry) = 1;
And finally I've invoked ST_BuildArea so to get back
yet again a Polygon from its Exterior Ring for each
Local Council:
CREATE TABLE com3 AS
SELECT nome_com, ST_BuildArea(geom) AS geom
FROM com2;
Let's now examine "com3" so to check the output from ST_BuildArea:
SELECT Count(*), GeometryType(geom) AS type
FROM com3
GROUP BY type;
----
9|NULL
7609|POLYGON
Provisional conclusion: ST_BuildArea() seems to work as expected
in many cases, but sometimes it will "mysteriously" fail (NULL).
Just a simple further check and I was finally able to discovered
why ST_BuildArea() sometimes returns NULL values:
SELECT nome_com
FROM com3
WHERE geom IS NULL
INTERSECT
SELECT nome_com
FROM com2011
WHERE ST_IsValid(geometry) = 0;
-----
Bogliasco
Bronte
Calasetta
Castellammare del Golfo
Giovinazzo
Isola Sant'Antonio
Rutigliano
Sannicandro di Bari
Tropea
Final conclusion: ST_BuidArea() will correctly refuse to return
a Polygon if the candidate Exterior Ring does contain some
invalidity cause (e.g. self-intersections, spikes and alike).
So after all it's not a a bug, and looks more like a good-minded
feature.
That's not at all surprising, once considered that SpatiaLite
simply delegates the actual task to reassemble Polygons from
Linestrings to GEOS, and GEOS is notoriously fussy about
invalidities.