Original answer
This works up to Postgres 9.6. The behavior of set-returning functions in the SELECT list was changed (sanitized) in Postgres 10. See below!
Upon revisiting this question it struck me that this can be simpler and faster.
Reverse the logic of the currently accepted solution by @a_horse:
SELECT id, CASE WHEN values <> '{}' THEN unnest(values) END AS value
FROM tbl;
fiddle
This returns a row with NULL in value for an empty array as well as for a NULL array, because only an array with elements in it produces TRUE in the test values <> '{}'.
Works for arrays of any type, since the literal '{}' is automatically coerced to a matching type.
Without explicit ELSE branch, CASE returns NULL, which is what we want anyway.
Arrays with a NULL elements will return rows regardless.
However. I found an anomaly and posted a question concerning that:
Turned out to be a bug that was fixed after my report for pg 9.3+.
Since Postgres 10
The short syntax above stops working after the behavior of set-returning functions in the SELECT list has been reworked (sanitized). See:
A LATERAL subquery is the clean, versatile solution, and works since Postgres 9.3, where LATERAL was added:
SELECT t.id, v.value
FROM tbl t
LEFT JOIN LATERAL unnest(t.values) AS v(value) ON true;
Or, with minimal syntax:
SELECT id, value
FROM tbl
LEFT JOIN LATERAL unnest(values) value ON true;
fiddle
See: