It's also worth noting that in systems that don't optimise across CTE boundaries (I believe Postgres is one of these), they usually do still optimise across view boundaries. CREATE TEMPORARY VIEW is your friend
... that seems thoroughly backwards to me, at least in terms of expectations. I mean, I know that views that were optimization boundaries wouldn't be useful, but just from an intuitive perspective I'd expect that the stand-alone database objects would be optimization boundaries while the query-supporting statements would be optimized as part of the query.