# INSERT {bdg-primary-line}`GQL clause` {bdg-secondary-line}`Added in 2.18` Creates the vertices and edges a pattern describes. It is the GQL name for the clause Cypher calls `CREATE`. ## Synopsis
INSERT [ path_variable = ] pattern [, [ path_variable = ] pattern ] ...

bold keywords · italic placeholders you supply · [ ] optional · ... repeatable. See Syntax conventions.

## Description `INSERT` and [`CREATE`](create.md) are the same clause under two names. The parser builds an identical tree for both, so they accept the same patterns, raise the same errors and produce the same plan. - Every element in the pattern is created, except one already bound to a variable in scope. That element is reused as an endpoint and not duplicated. - An `INSERT` runs once per input row. With no preceding clause it runs once. - Variables the pattern binds are visible to the clauses that follow, and to later patterns in the same `INSERT`. - Every edge needs exactly one label and a direction. Labels must already exist unless `enable_graph_ddl` is on to create them implicitly. ## Parameters path_variable : Optional name bound to the whole path the pattern created. Returning it yields a `graphpath` value listing the new vertices and edges in order. pattern : A vertex or path pattern, as described in [Syntax](../syntax.md). Property maps may be written inline (`{title: 'Tenet'}`) or supplied whole with `=` from an expression, including a SQL subquery. ## Examples Every example runs against [the example dataset](../../get_started/example-dataset.md). Add one film. `INSERT` and `CREATE` are interchangeable. Switch tabs to compare: ::::{tab-set} :::{tab-item} GQL — INSERT ```cypher INSERT (:movie {title: 'Tenet', year: 2020, genre: 'Action'}); ``` ::: :::{tab-item} Cypher — CREATE ```cypher CREATE (:movie {title: 'Tenet', year: 2020, genre: 'Action'}); ``` ::: :::: ``` UPDATE 1 ``` Both plan identically: ```cypher EXPLAIN (COSTS OFF) INSERT (:movie {title: 'Tenet'}); ``` ``` QUERY PLAN -------------- Graph Create -> Result (2 rows) ``` ### Return what you created `INSERT` binds its variables like any other clause, so a following `RETURN` can report them: ```cypher INSERT (p:person {name: 'John David Washington', born: 1984}) RETURN p.name AS person; ``` ``` person ------------------------- "John David Washington" (1 row) ``` ### Attach a new element to one already in the graph A variable bound by a preceding `MATCH` is an endpoint, not a new vertex, so only the edge is created: ```cypher MATCH (p:person {name: 'Christopher Nolan'}), (m:movie {title: 'Tenet'}) INSERT (p)-[:directed]->(m) RETURN count(*) AS edges; ``` ``` edges ------- 1 (1 row) ``` ### Build several patterns in one clause Patterns are separated by commas and may refer to variables earlier patterns bound: ```cypher MATCH (m:movie {title: 'Tenet'}) INSERT (a:person {name: 'Robert Pattinson', born: 1986}), (b:person {name: 'Elizabeth Debicki', born: 1990}), (a)-[:acted_in {role: 'Neil'}]->(m), (b)-[:acted_in {role: 'Kat'}]->(m); ``` ``` UPDATE 4 ``` The tag counts the four elements the one clause created: ```cypher MATCH (p:person)-[r:acted_in]->(:movie {title: 'Tenet'}) RETURN p.name AS actor, r.role AS role ORDER BY actor; ``` ``` actor | role ---------------------+-------- "Elizabeth Debicki" | "Kat" "Robert Pattinson" | "Neil" (2 rows) ``` ### Take a property map from a SQL query The `= expression` form supplies the whole map at once. Use it to load properties out of a table: ```cypher INSERT (:movie = (SELECT jsonb_build_object('title', 'Dunkirk', 'year', 2017))); ``` ``` UPDATE 1 ``` ```cypher MATCH (m:movie {title: 'Dunkirk'}) RETURN m.year AS year; ``` ``` year ------ 2017 (1 row) ``` ## Notes The clause reports its ordinary graph-write command tag, `UPDATE n`, rather than a `CREATE` tag. Pair it with [`FINISH`](finish.md) when you want a write and no projection. Refusals name `CREATE` even when you wrote `INSERT`, because both spellings build the same clause. The ones worth knowing: | Pattern | Error | | --- | --- | | `INSERT ()-[]->()` | `only one relationship type is allowed for CREATE` | | `INSERT ()-[:acted_in\|directed]->()` | `only one relationship type is allowed for CREATE` | | `INSERT ()-[:directed]-()` | `only directed relationships are allowed in CREATE` | | `INSERT (:ag_vertex)` | `specifying default label is not allowed` | | `INSERT ()-[:ag_edge]->()` | `cannot create edge on default label` | | `INSERT (:directed)` | `label "directed" is edge label` | | `INSERT ()-[:movie]->()` | `label "movie" is vertex label` | | `INSERT (m)` where `m` is already bound | `there must be at least one relationship` | ```{note} `insert` became a reserved keyword in 2.18. It is still accepted unquoted wherever that leaves the grammar unambiguous — as a variable name, `MATCH (insert:person)`, and as a label name in a pattern, `MATCH (n:insert)`. It is not accepted as a `CREATE VLABEL` name, as an `ORDER BY` key naming a `RETURN` alias, or as a SQL table or column name; write `"insert"` there, or rename. ``` ## Compatibility ```{admonition} GQL conformance :class: gql-conformance Implements the GQL *INSERT statement* (ISO/IEC 39075:2024 §13.2) over the *insert graph pattern* of §16.5. - **Supported** — inserting nodes and edges, several patterns per statement, reusing a bound element as an endpoint, inline property maps, and a path variable over the inserted pattern. - **Not supported** — the standard's typed-graph checks (§18), which require a graph type; AgensGraph graphs are untyped, so an insert is validated against the labels that exist rather than against a declared node or edge type. Track status in the [GQL conformance matrix](../../appendix/gql-conformance.md). ``` ### openCypher openCypher spells this clause `CREATE`, which AgensGraph accepts as a synonym. The `INSERT` name comes from GQL and from SQL, where it does the same job on a table. ## See also - [`CREATE`](create.md) — the Cypher synonym, same clause - [`MERGE`](merge.md) — create only what is not already there - [`FOR`](for.md) {bdg-secondary-line}`GQL` — drive an `INSERT` once per list element - [`FINISH`](finish.md) {bdg-secondary-line}`GQL` — write without projecting - [Syntax](../syntax.md) — the pattern grammar `INSERT` takes - [GQL conformance matrix](../../appendix/gql-conformance.md)