Insert basics — AQL
Insert
Section titled “Insert”insert User { email := $email, name := $name, age := $age};-- $1: email-- $2: name-- $3: ageINSERT INTO "user" ("email", "name", "age")VALUES ($1, $2, $3)RETURNING *;Inserting with a link
Section titled “Inserting with a link”Assign a link by passing a subquery that resolves to the FK value.
insert Post { title := $title, author := (select User filter .email = $email)};-- $1: title-- $2: emailINSERT INTO "post" ("title", "author")VALUES ($1, (SELECT u.id FROM "user" u WHERE u.email = $2 LIMIT 1))RETURNING *;The SQL samples on these pages write
RETURNING *for brevity. Axel actually emits the explicit column list of the inserted row —RETURNING "id", "title", "author"for the query above — which is what the generated row type is built from.
A link assignment accepts any scalar expression that resolves to the FK value, not just a solo subquery:
-
A bare parameter — pass the FK directly; a lone link param infers
uuid.insert Post { title := $title, author := $author_id }; -
A subquery projection — select a linked FK column rather than the row id with
(select …).link.insert GithubInstallation {organization := (select GithubInstallation filter .installation_id = $iid<int64>).organization,installation_id := $iid<int64>}; -
A
??chain — coalesce several lookups; the FK resolves from whichever finds a row first.insert GithubInstallation {organization := (select Organization filter .id = $org<uuid>?)?? (select GithubInstallation filter .installation_id = $iid<int64>?).organization,installation_id := $iid<int64>};See Optional parameters — value subquery for how an omitted param lets the chain fall through.
-
A sub-insert — create the linked row inline; it lowers to a CTE. See Conflicts for the (unsupported) interaction with
unless conflicton sub-inserts.insert Post {title := $title,author := (insert User { email := $email, name := $name })};
To handle a uniqueness collision, see Conflicts. To reassign a link on an existing row, see Updating links.