Set non-negative floor for rolling sum, in PostgreSQL
This is how I solved a similar problem on Teradata using nested OLAP-functions:

SELECT dt.*,
   -- find the lowest previous CumSum &lt; 0       
   -- and adjust the current CumSum to zero
   Max(CASE WHEN CumSum &lt; 0 THEN -CumSum ELSE 0 end)
       Over (PARTITION BY groupid
             ORDER BY pkid
             ROWS Unbounded Preceding)
   + CumSum AS AdjustedSum
FROM 
 ( 
   SELECT pkid, numvalue, groupid,
      -- calculate a standard cumulative sum
      Sum(numvalue)
      Over (PARTITION BY groupid
            ORDER BY pkid
            ROWS Unbounded Preceding) AS CumSum
   FROM foo
 ) AS dt