Hello list, I have a few clarification questions regarding using insert with returning. The use case is SQLAlchemy development, where the orm wants to insert a list of rows, get back the generated ids, defaults, etc, and match the returned values with the original list of orm objects. The following assumes a table like this CREATE TABLE t( id SERIAL, data TEXT -- type here can be anything ) On PostgreSQL, since SQLAlchemy version 1.4 (Mar 2021) this operation has used INSERT INTO t(data) VALUES ('a'), ('b'), ('c') RETURNING id but we were recently made aware that there is no guarantee on the order of the returned columns. Looking at the documentation there is no mention of the order of the RETURNING clause, but searching past discussion there are multiple indication that the order is not guaranteed, like https://www.postgresql.org/message-id/19445.1350482182%40sss.pgh.pa.us . I think the docs should mention this, similar to what the sqlite docs do at https://www.sqlite.org/lang_returning.html#limitations_and_caveats Searching the archive seems that a using the INSERT SELECT ORDER BY form should be a better solution, so the above insert should be rewritten as INSERT INTO t(data) SELECT data FROM (VALUES ('a', 1), ('b', 2), ('c', 3)) as vv(data, num) ORDER BY num RETURNING id to ensure that the id are created in the order specified by num. The returned id can again be in arbitrary order, but sorting them should enable correctly matching the orm object so that they can be properly updated. Is this correct? The documentation does not say anything about this, and looking at the archive it seems that it's mostly correct but not 100% guaranteed, as stated here https://www.postgresql.org/message-id/29386.1528813619%40sss.pgh.pa.us . The MSSQL docs, for example, clearly state that this is the case https://learn.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql?view=sql-server-ver16#limitations-and-restrictions , so it would be helpful if something similar were mentioned in the PostgreSQL docs. The above insert form (INSERT SELECT ORDER BY) can be used when the primary key is an auto incrementing value, in case it isn't (such as when it's an UUID), another solution must be used. Since there does not seem to be any way of getting the position of the original row inside the VALUES clause with RETURNING, the solution SQLAlchemy is implementing is to either degrade to inserts with a single value or to optionally allow the user to add a "sentinel" column to the table, so that a sequential value can be inserted into it and then returned allowing the ordering of the RETURNING clause rows: ALTER TABLE t ADD COLUMN sentinel SMALLINT INSERT INTO t(data, sentinel) VALUES ('a', 1), ('b', 2), ('c', 3) RETURNING id, sentinel Is there any better solution to achieve this? (For reference this feature is tracked in SQLAlchemy by https://github.com/sqlalchemy/sqlalchemy/issues/9618) >From an ORM standpoint it would be very useful having a way of forcing the order of RETURNING to be the same as the one in VALUES, maybe with an additional keyword. Alternatively having a system column or other function that can be placed into the returning clause to return the output row position wrt the input values list, similar to what the sentinel column above does. At the very least I think the documentation could do a better job at mentioning that RETURNING order is arbitrary, and documenting that INSERT SELECT ORDER BY precesses the default in select order (if that's indeed the case) Sorry for the long email, Thanks Federico