I asked over on the Postgres mailing-list and they were helpful in clarifying. It turns out that this is a database specific answer, so if you're reading this and using a different database the answer may not be the same.
Postgres, explicitly as of 9.6, will logically insert in the order of the returned result set.
The behavior is explicitly codified in this commit: https://github.com/postgres/postgres/commit/9118d03a8cca3d97327c56bf89a72e328e454e63
From the commit description:
For example, in SELECT x, nextval('seq') FROM tab ORDER BY x LIMIT
10; it's probably desirable that the nextval() values are ordered the
same as x, and that nextval() is not run more than 10 times.
In the past, Postgres was inconsistent in this area: you would get the
desirable behavior if the ordering were performed via an indexscan,
but not if it had to be done by an explicit sort step.
To quote the mailing list response from Tom Lane at https://www.postgresql.org/message-id/29386.1528813619%40sss.pgh.pa.us :
What is actually going to happen, given say
create table targ (d text, id serial);
insert into targ select x from src order by y;
is that you're going to get a parse tree equivalent to
select x, nextval('targ_id_seq')
from (select x from src order by y) ss;
and then it's a question of whether the planner is capable of reordering the steps into something you don't want. I think that the presence of the explicit "ORDER BY" in the sub-select will prevent flattening of the sub-select, which is enough to make it safe. However, if for some reason
you did not say "ORDER BY" but nonetheless expected the serial values to get assigned in the same order that the underlying query would produce rows natively, you might get burnt.
As of 9.6, there are more guarantees in this area than there used to be (cf commit 9118d03a8), but I don't think it matters as long as you write an ORDER BY.
tl;dr; The insertion ordering is an implementation detail, but purposefully coded in Postgres 9.6 and above to match one's intuition. Prior to 9.6, there were no guarantees.
ORDER BYdoes matter, and for SQL Server there are Microsoft people confirming this, too, I could find nothing for PostgreSQL (or Oracle for that matter) on the Internet. I think that this should clearly stated in the documentation. For PostgreSQL there is a link down in postgresql.org/docs/current/static/sql-insert.html leading you to a form where you should be able to ask them to include an explanation onORDER BYinINSERT SELECTin their docs.deleteand yet another "order" for a table that contained rows that were removed usingtruncateand yet another "order" if only half of the rows had been deleted. For aSELECTstatement the only (really: the only) way to get a guaranteed order is to use anorder by. There is no alternative to that.