This is the same result as happens with returning: true or returning: [:id].
(I picked a schema without timestamps, because it was the most convenient. I’m betting I could affect whether timestamps were returned with :returning. I’m nearly out of power. I’ll check if my understanding above is wrong.)
:returning - selects which fields to return. It accepts a list of fields to be returned from the database. When true , returns all fields. When false , no extra fields are returned. It will always include all fields in read_after_writes as well as any autogenerated id. Not all databases support this option.
PostgreSQL does support RETURNING on a detailed level (MySQL doesn’t seem to support it).
It could be informative to see the generated SQL through an iex session (example).
Changesets already hold all the data needed to return you the inserted value. :returning similar to :read_after_writes is only useful if your db has autogenerated values, defaults, triggers or such means to modify the value you’re persisting and you want to read it back, because what the changeset holds won’t match what the db stores.
The following appears to be true, and I’ll make a pull request against the documentation (better written than the below).
By default, insert receives only the new primary key (typically, :id) from the database. That id is merged with the data given to insert to produce what is usually a copy of the data in the database. The only exception is if the database itself changes or creates fields (with, for example, triggers). Here are returning's options:
true: asks the database to provide all the fields in the record (including ones whose value is already known. (This only works when the data comes from a schema struct.)
a list of fields: specify fields to be provided (always in addition to the primary key).
false: the same as giving no returning keyword: only the new primary key is provided.
:read_after_writes - When true, the field is always read back from the database after insert and updates.
For relational databases, this means the RETURNING option of those statements is used. For this reason, MySQL does not support this option and will raise an error if a schema is inserted/updated with read after writes fields.
What the documentation isn’t explicit about (likely assumed by implication) is that the returned values will replace the original values in the changeset :data.