ST_IsValidDetail
Name
   ST_IsValidDetail — Returns a
   
    valid_detail
   
   row stating if a geometry is valid or if not a reason and a location.
  
Synopsis
    
     valid_detail
     
      ST_IsValidDetail
     
     (
    
    geometry
    
     geom
    
    , integer
    
     flags
    
    
     )
    
    ;
   
Description
   Returns a
   
    valid_detail
   
   row,
        containing a boolean (
   
    valid
   
   ) stating if a geometry is valid,
        a varchar (
   
    reason
   
   ) stating a reason why it is invalid
        and a geometry (
   
    location
   
   ) pointing out where it is invalid.
  
Useful to improve on the combination of ST_IsValid and ST_IsValidReason to generate a detailed report of invalid geometries.
   The optional
   
    flags
   
   parameter is a bitfield. It can have the following values:
  
- 
     
0: Use usual OGC SFS validity semantics.
 - 
     
1: Consider certain kinds of self-touching rings (inverted shells and exverted holes) as valid. This is also known as "the ESRI flag", since this is the validity model used by those tools. Note that this is invalid under the OGC model.
 
Performed by the GEOS module.
Availability: 2.0.0
Examples
--First 3 Rejects from a successful quintuplet experiment
SELECT gid, reason(ST_IsValidDetail(geom)), ST_AsText(location(ST_IsValidDetail(geom))) as location
FROM
(SELECT ST_MakePolygon(ST_ExteriorRing(e.buff), array_agg(f.line)) As geom, gid
FROM (SELECT ST_Buffer(ST_Point(x1*10,y1), z1) As buff, x1*10 + y1*100 + z1*1000 As gid
	FROM generate_series(-4,6) x1
	CROSS JOIN generate_series(2,5) y1
	CROSS JOIN generate_series(1,8) z1
	WHERE x1 > y1*0.5 AND z1 < x1*y1) As e
	INNER JOIN (SELECT ST_Translate(ST_ExteriorRing(ST_Buffer(ST_Point(x1*10,y1), z1)),y1*1, z1*2) As line
	FROM generate_series(-3,6) x1
	CROSS JOIN generate_series(2,5) y1
	CROSS JOIN generate_series(1,10) z1
	WHERE x1 > y1*0.75 AND z1 < x1*y1) As f
ON (ST_Area(e.buff) > 78 AND ST_Contains(e.buff, f.line))
GROUP BY gid, e.buff) As quintuplet_experiment
WHERE ST_IsValid(geom) = false
ORDER BY gid
LIMIT 3;
 gid  |      reason       |  location
------+-------------------+-------------
 5330 | Self-intersection | POINT(32 5)
 5340 | Self-intersection | POINT(42 5)
 5350 | Self-intersection | POINT(52 5)
 --simple example
SELECT * FROM ST_IsValidDetail('LINESTRING(220227 150406,2220227 150407,222020 150410)');
 valid | reason | location
-------+--------+----------
 t     |        |