Chapter 14Data Modification
This chapter formalizes how GQL data-modification statements transform the underlying property-graph store, treating updates as structured deltas that map one graph state to another. We give a declarative description of the insertion and deletion of graph elements and the in-place modification of labels and properties, and explain how these operations compose with pattern-based reads, identifier allocation, and constraint checking. The model makes implementation-defined details such as reference value types explicit, but is otherwise independent of any particular execution strategy.
Semantic interfaces used in this chapter. Let denote the domain of graph-type descriptors. A graph entry has the abstract form
where is its graph, is either a reference to a descriptor in or , and is the dictionary of constraints defined directly on the graph. The current working graph site has a declared graph-reference type and is occupied by a graph reference value. That reference identifies the graph denoted here by ; its corresponding graph entry or graph descriptor supplies the optional constraining graph-type reference and constraint dictionary. Write for that entry or descriptor. When the graph is written , denotes the corresponding active entry or descriptor. Let denote the domain of session authorization identifiers and let denote the identifier under which a statement is executed. Finally, let denote the domain of five-character GQLSTATUS codes. To raise a code is to produce a failed outcome, which has no statement result. Let denote an omitted statement result, and write for a successful outcome whose result is , abstracting over its status objects; this is the projection of the outcome defined in Chapter 21. The later chapters on types, constraints, catalogs, authorization, and diagnostics refine these interfaces.
Implementation configuration. We make the implementation-defined choices used below explicit by an implementation configuration . Formally, let
where:
- are implementation-defined reference value types for nodes and edges;
- and are the supported minimum and maximum cardinalities of node and edge label sets, respectively;
- are the supported maximum numbers of node and edge properties.
For the current working graph , the constraint dictionary in contains the constraints defined directly for that graph. After a data-modifying operation, those constraints are dynamically validated against the modified graph. The subsequent graph-type conformance check, when a constraining graph type is present, also accounts for the constraints of that graph type. Constraints registered for unrelated graph or graph-type subjects are not consulted.
Whenever we write “implementation-defined” in this chapter, the corresponding choice is assumed to be represented in .
Syntactic frame for data modification. At the concrete-syntax level, a linear data-modification statement is a pipeline consisting of an optional graph-selection header followed by simple data-accessing steps, at least one of which is data-modifying, and an optional primitive result statement at the end. The following highly simplified BNF captures this spine; detailed productions for each kind of query and DML primitive are given in later sections.
linear-dm-stmt ::= [ "USE" graph-expr ] dm-body [ result-step ]
dm-body ::= { data-access-step } dm-primitive
{ data-access-step }
data-access-step ::= query-step | dm-primitive
dm-primitive ::= insert-stmt
| set-stmt
| remove-stmt
| delete-stmt
| "CALL" dm-procedure /* data-modifying procedure */
query-step ::= ... /* simple query statement */
result-step ::= ... /* FINISH, RETURN, or SELECT; final only */
graph-expr ::= ... /* graph reference / expression */
dm-procedure ::= ... /* procedure name + arguments */
Semantically, the query steps determine a working table of bindings, while the data-modification primitives contribute a staged write-set (delta) relative to a chosen graph. The remainder of this chapter explains how the primitives in dm-primitive contribute node/edge insertion, deletion, and property/label updates, and how the resulting delta is validated and applied.
The simple data-modification statements require optional feature GD01; label additions and removals require GD02. A delete item containing a procedure body requires GD03; one simply containing a value expression other than a binding-variable reference requires GD04. Insertion of an undirected edge requires GH02.
14.1 INSERT and CREATE
An INSERT statement inserts new nodes and edges into the current working graph. Its body is an insert graph pattern composed of insert path patterns that (i) may declare element variables for newly created nodes/edges and (ii) may specify label and property sets for those elements. The statement has an empty declared type and returns an omitted result; it may, however, augment the working table with columns for declared element variables (see below).
Concrete syntax for INSERT. At the level of concrete syntax, INSERT uses a compact, path-shaped notation that mirrors the pattern language of MATCH. New nodes and edges are described by node and edge patterns, which may optionally introduce element variables, label lists, and property maps. The following simplified BNF sketch outlines the core structure of the INSERT pattern language.
insert-stmt ::= "INSERT" insert-pattern
insert-pattern ::= insert-path { "," insert-path }
insert-path ::= node-pattern { edge-pattern node-pattern }
node-pattern ::= "(" [ var ] [ ( ":" | "IS" ) label-set ]
[ property-map ] ")"
edge-pattern ::= "-[" [ var ] [ ( ":" | "IS" ) label-set ]
[ property-map ] "]->"
| "<-[" [ var ] [ ( ":" | "IS" ) label-set ]
[ property-map ] "]-"
| "~[" [ var ] [ ( ":" | "IS" ) label-set ]
[ property-map ] "]~"
label-set ::= label { "&" label }
property-map ::= "{" ... "}" /* key: value pairs,
as in expressions */
var ::= identifier
label ::= identifier
Intuitively, each insert-path contributes one or more insert node/edge patterns to the abstract insert graph pattern : an isolated node-pattern describes a node insertion, while each adjacent edge-pattern node-pattern extends the path with an edge and node. The semantic clauses below reinterpret these syntactic patterns as scheduled insertions of nodes and edges, equipped with label and property sets derived from the specified label lists and property maps. The undirected form requires optional feature GH02.
Typing and new columns. An insert element pattern is bound if the name of its declared element variable already occurs as a column of the incoming working table type or as a field of the incoming working record type. Its declared type is inherited from that column or field. Such a pattern reuses the corresponding incoming node reference and does not introduce a new column.
For every other insert element pattern in that declares an element variable by name , INSERT contributes a column named whose type is an implementation-defined reference value type covering all nodes (resp. edges) that INSERT can bind to . If that type is closed, then each property key/value in the pattern is store-assigned as if to a transient site of the corresponding property type. Columns whose names are system-generated in (introduced when an element variable name is omitted) are removed from the outgoing working table. The incoming record type is preserved; the outgoing table type equals the union of the incoming columns and the new columns, minus the system-generated ones. The current working graph site must be defined.
Operational semantics. Let be the current working table, let be the graph referenced by the current working graph site, and let be the set of system-generated variable names introduced by . Execution of transforms these objects according to
provided that no exception is raised. Here is obtained from by performing all node and edge insertions scheduled by the procedure below, and is obtained by extending each input record with reference values for the newly inserted graph elements declared by non-bound insert element patterns, and then removing the columns whose names are system-generated.
Initially, let be an empty binding table whose columns are the union of the columns of and the columns contributed by the element variables declared by non-bound insert element patterns in . For each record , process in a fresh child execution context amended with . Construct a record containing the reference values of the graph elements created for , by processing each insert path pattern immediately contained in as follows:
-
Inserting node pattern. For every insert node pattern that is the defining pattern for an element variable , has the name , and is not a bound insert element pattern:
- Determine the node label set , taking if no label set is specified. Enforce the implementation-defined minimum and maximum node-label-set cardinalities. If is below the supported minimum, raise 22G0N (number of node labels below supported minimum); if it exceeds the supported maximum, raise 22G0P (number of node labels exceeds supported maximum).
- Compute the node property set from the property key/value list, taking if no such list is specified. Each property value expression is evaluated in the child execution context and store-assigned to the corresponding new property. If the number of properties exceeds the implementation-defined maximum, raise 22G0S (number of node properties exceeds supported maximum).
- Schedule the insertion into of a new node with a new global object identifier, label set , and property set . Let be the node reference value for , and include in the field named with value . The same reference value is used by other insert element patterns that refer to this defining node pattern.
-
Inserting edge pattern. For every insert edge pattern that declares an element variable with name :
-
Determine the edge label set , taking if no label set is specified, and enforce the implementation-defined minimum and maximum edge-label-set cardinalities. If is below the supported minimum, raise 22G0Q (number of edge labels below supported minimum); if it exceeds the supported maximum, raise 22G0R (number of edge labels exceeds supported maximum).
Compute the edge property set analogously, evaluating each property value expression in the child execution context and store-assigning its result to the corresponding new property. If the number of properties exceeds the implementation-defined maximum, raise 22G0T (number of edge properties exceeds supported maximum).
-
Determine the left and right endpoint nodes from the nearest surrounding insert node patterns. If an endpoint pattern is a bound insert element pattern, use the node denoted by its bound element variable; otherwise, use the node reference value computed for its defining insert node pattern. If either endpoint node is deleted, raise G1002 (endpoint node is deleted). If either endpoint node is not in the current working graph, raise G1003 (endpoint node not in current working graph).
Determine whether the new edge is directed or undirected from the syntactic form of . For a directed edge, use the arrow orientation to determine which endpoint is the source and which is the destination.
- Schedule the insertion into of a new edge with a new global object identifier, label set , property set , and the determined endpoints, direction, and orientation. Let be the edge reference value for , and include in the field named with value .
-
After all immediately contained insert path patterns have been processed for , construct a record by amending with , and append to .
After all records of have been processed, perform all scheduled node insertions, followed by all scheduled edge insertions. Let be the resulting provisional graph. Dynamically validate every direct constraint on ; an enforcement failure raises 23000 (integrity constraint violation). If has a constraining graph type and is not of , raise G2000 (graph type violation). Consequently, a successful INSERT has passed the required direct-constraint validation and graph-type conformance check, including the constraints of that graph type.
Finally, let be a copy of with all columns whose names belong to removed, and set as the current working table. The execution outcome is successful with an omitted result; thus, INSERT modifies the graph and propagates the extended working table, but does not itself return a result value. See Section 4.3 for a complete insertion of library nodes, edges, labels, and properties.
Identifiers and allocation. Every created graph element (node or edge) receives a new global object identifier; copies likewise obtain fresh identifiers. Reference values reify globally resolved references to such objects. Element variable names that the syntax supplies automatically are system-generated regular identifiers and are not retained as output columns.
CREATE GRAPH (catalog). A CREATE GRAPH statement creates a new graph using an open ANY graph form or constraining it by an existing graph type reference, an inline graph type specification, or a graph type LIKE another graph. When a source graph is provided, all nodes and edges are copied into the new graph and each copy is assigned a new global object identifier. The created graph descriptor records the constraining graph type (if any). A violation of a constraint defined directly on the graph raises 23000; a graph-type violation raises G2000.
14.2 DELETE
Concrete syntax for DELETE. DELETE statements operate on a list of expressions whose declared types are graph-element reference value types. At runtime, valid node and edge references are collected for deletion, while the null value and invalidated references are ignored without accessing their referents. An optional prefix keyword controls whether incident edges are automatically removed or must already be absent. The following simplified BNF captures the core concrete form:
delete-stmt ::= [ "DETACH" | "NODETACH" ] "DELETE"
delete-arg { "," delete-arg }
delete-arg ::= expr /* must evaluate to a node or
edge reference */
expr ::= ... /* value expression */
Intuitively, a delete-stmt with NODETACH (or without any prefix, for which GQL makes NODETACH implicit) is interpreted using the plain delete semantics below, which require that every incident edge of a deleted node is also designated for deletion. A statement prefixed by DETACH is interpreted using the detach delete semantics, which first removes incident edges and then removes the node itself. In both cases, the deletion of edges referenced directly by delete-arg follows the edge-deletion rules outlined next.
Plain DELETE. A plain DELETE, for which NODETACH is implicit, first collects the sets and of nodes and edges designated for deletion. For every , deletion is permitted only if
otherwise, the statement signals a dependent-object error (G1001, edges still exist). Every is deleted unconditionally, without affecting its endpoint nodes. If the condition holds for all , all designated nodes and edges are deleted atomically, together with their labels and properties.
Example (plain deletion of an edge).
USE libraryGraph
MATCH (l:Loan)-[i:INCLUDES]->(b:Book)
WHERE b.isbn = '978-83-987...'
DELETE i
INCLUDES
edge; its endpoint nodesl
andb
remain in the graph.DETACH DELETE. For a node , adds every edge to the set of elements to be deleted and then deletes . It does not recursively delete nodes adjacent to . Additional nodes must be designated explicitly by including them as separate items in the comma-separated delete-item list, as in . See Section 4.3 for a concrete use of DETACH DELETE in the library graph.
Constraint validation. The sets of nodes and edges to be deleted, including the incident edges added by DETACH, are collected before any deletion is performed. The resulting copy is then checked as one atomic result. Its direct constraints are dynamically validated, and, if the graph has a constraining graph type, is checked for conformance to that type. Deleting elements cannot by itself create a violation of the key or unique constraints defined by GQL. A graph-type violation raises G2000; this check is retained for implementation-defined extensions and future graph-type constraints even though the constraints currently defined by GQL do not make it reachable by deletion alone.
14.3 Read-then-Update Composition
A data-modifying statement commonly combines a read phase with an update phase. The read query is evaluated first against the current graph state , under the authorization context of principal , producing a binding table
Each record in identifies graph elements or supplies values that may be used by the subsequent update . Thus, the result of does not itself modify the graph; rather, it determines the bindings with respect to which is evaluated.
For an update part , graph , binding table , and authorization identifier , write for the coalesced update delta produced by evaluating for all records of , as defined concretely in Section 14.4. The partial expression denotes application of a delta to . Let be the active graph entry. The full validation predicate is
The update phase computes a graph delta
which collects the insertions, deletions, label changes, and property changes requested by for the bindings produced by . Conceptually, is evaluated for the records of , and the individual changes are combined into a single delta. If is empty, an update whose effects depend entirely on those bindings normally produces the empty delta and leaves the graph unchanged.
The denotation of the composed read-then-update operation is
Here, denotes the graph obtained by applying the complete delta to . The authorization condition covers both access to the data inspected by and permission to perform the modifications requested by . The predicate states that the delta is applicable to , that the resulting graph satisfies every direct constraint, and that it conforms to its constraining graph type, including the constraints of that graph type.
Accordingly, the composition is atomic at the level of this denotation: either the complete authorized and valid delta is applied, producing the new graph state, or the operation yields an error and no resulting graph state is defined by the statement.
14.4 Write-Set Coalescing and Conflicts
Concrete syntax for SET. A SET statement updates properties and labels of elements named by variables that are bound by preceding query steps (for example, by MATCH). Each item in the SET list either assigns a single property, replaces the entire property map, or adds a label to the element’s label set. The following simplified BNF describes the core concrete form:
set-stmt ::= "SET" set-item { "," set-item }
set-item ::= var "." prop "=" expr
| var "=" "{" ... "}" /* replace all properties of var */
| var ( ":" | "IS" ) label /* add label to var */
var ::= identifier /* binding variable from MATCH, etc. */
prop ::= identifier /* property name */
label ::= identifier
expr ::= ... /* value expression */
Informally, a set-item of the first form assigns a value to a single property of the element denoted by var, the second form replaces all existing properties of that element by the given map, and the third form adds a label to the element’s label set (using either the shorthand var:Label or the more verbose var IS Label). In the semantic model below, these surface forms are reinterpreted as combinations of primitive property-setting, property-clearing, and label-addition atoms that constitute an update template. See Section 4.3 for a concrete read-then-SET operation on a library edge property.
Update context. For a graph pattern , predicate , and concrete write part , an update pipeline is represented at the meta-level as
where is meta-notation, not a GQL keyword; examples of include SET, REMOVE, and DELETE. The read part yields a bag of mappings over variables (node-, edge-, and path-variables). Updates are then staged per and coalesced before application to the transaction-visible working state.
Targets. Evaluation of a target binding-variable reference under yields either a graph-element reference or the null value. A null target contributes no modification. A target reference that is used for an update is therefore either a node-id or an edge-id ; accessing the referent of an invalidated reference raises 22G11. We write for the valid targets referenced by under .
Update atoms. For , , , , and a value expression , the primitive update atoms are listed below. Here denote the provisional post-update maps obtained from by the indicated assignment; every unmentioned map entry is unchanged.
The two property-setting rows abbreviate the standard store-assignment rules, including their nullability and conversion checks. A surface item var = {...} contributes the appropriate CLEAR atom followed by one property-setting atom for each property pair in textual order. Endpoint reattachment is not an in-place update; changing endpoints is modeled as deletion followed by recreation.
Notational shorthands (ground update operations). The primitive atoms above mix two concerns: (i) the target (a concrete node/edge id) and (ii) an r-value expression that must be evaluated under a mapping . For examples and for write-set reasoning, it is convenient to use ground operations where the r-value has already been evaluated to a concrete value.
Let be a node identifier, an edge identifier, a property key, a label, a value expression, and a concrete value. Let be the function that maps update atoms to ground operations by evaluating r-values under . We use the following shorthands:
Thus, for example, abbreviates the ground effect “set the vertex-property to the value ”.
Templates and determinism. An update template is a finite, textually ordered list of atoms whose l-values are expressions over . For a fixed , evaluation produces a per-binding write-set , represented as a list of ground operations on concrete element identifiers. Concretely, is obtained by applying to the atoms of , evaluating all r-values under , while preserving their textual order. A set item whose target is null contributes the empty list. A set-all- properties item contributes a clear operation followed by its evaluated property assignments; an attempted access through an invalidated target raises 22G11 rather than contributing a write.
Standard options. For a single SET statement that would make multiple assignments to the same , even if the assigned values are equal, the GQL standard specifies an implementation-defined choice between two behaviors:
- signal data exception 22G0M, or
- make an implementation-dependent choice of one assignment.
In this book we adopt a canonical partial coalescer that realizes option (a) while preserving the order of records and set items required by the standard. Property-assignment operations are pairwise compatible only when they target distinct pairs. Label additions commute, and repeated additions of the same label to the same element are idempotent and may coalesce to one effective addition. Clear-all-properties operations are retained at their ordered positions. Whenever two property assignments target the same in one statement, is undefined and the statement signals 22G0M. Different -instances are folded in incoming-table order, subject to these rules.
Staged delta and application. Identifying the binding table with its bag of mappings, the staged delta introduced in Section 14.4 is
where the indexed folds the partial coalescer and is defined only when the combined write-set is pairwise-compatible as above. Within this section, abbreviates . Applying the ordered to yields by clearing property sets for set-all-properties items, performing their property assignments in textual order, overwriting individual properties, adding labels, and leaving all other components unchanged. After each non-null set item, exceeding the supported maximum for a node label set, node property set, edge label set, or edge property set raises 22G0P, 22G0S, 22G0R, or 22G0T, respectively. The direct constraints on are dynamically validated against . If has a constraining graph type and is not of , the statement raises G2000; this conformance check includes the constraints of .
Read stability. All l-values and r-values in are evaluated over the pre-update working state that produced . Thus, intra-statement reads do not observe effects of the same statement’s writes; only the final is materialized atomically. This statement-level evaluation rule does not by itself select the transaction isolation extension discussed in Chapter 19.
Examples of coalescing and conflict detection. The following examples illustrate how the canonical coalescer handles repeated updates generated by bag-valued pattern matching. The first example considers multiple identical and idempotent label additions, which can be safely reduced to a single effective update. The second considers incompatible property writes to the same target and property key, which cannot be coalesced and therefore result in an intra-statement conflict.
(A) Idempotent label addition under bag matches. Suppose the read pattern matches the same vertex with multiplicity . Formally, the match result is a bag that contains five mappings such that the l-value of the label update refers to under each mapping (e.g., for ). Let the write part be a single label-add atom .
Then, for each , evaluation of the template yields the same per-binding write-set:
Hence, the staged delta is obtained by folding these five identical contributions:
Because label addition is idempotent and duplicates are pairwise compatible under the canonical coalescer, the five identical atoms coalesce into a single effective update:
Therefore, although matches five times, the statement is equivalent, with respect to the final store state, to a single addition of to .
(B) Conflicting property writes. Consider a mapping and two syntactically distinct l-values, for example x.k and y.k, that satisfy the static non-duplication rule but whose variable references alias at runtime: . Assume that their expressions produce two different ground writes to the same pair :
Equivalently, this arises from the atoms
such that and .
Under the standard-permitted option (a) adopted by the canonical model here, the coalescer is defined only for pairwise-compatible operations. Since the two ground writes target the same pair but prescribe different values, their union is not compatible. Consequently, is undefined, the indexed rejects the combined write-set, and the statement signals 22G0M, irrespective of the textual ordering of the two writes.
Concrete syntax for REMOVE. A REMOVE statement removes properties and labels from elements named by variables that are bound by preceding query steps (typically by MATCH). The following simplified BNF mirrors the style of SET and isolates the core concrete form of the statement:
remove-stmt ::= "REMOVE" remove-item { "," remove-item }
remove-item ::= var "." prop
| var ( ":" | "IS" ) label
var ::= identifier /* binding variable from MATCH, etc. */
prop ::= identifier /* property name */
label ::= identifier /* label name */
Each remove-item uses a binding variable whose declared type is a graph-element reference (node or edge). The first form var.prop schedules the removal of a single property (if present) from the element denoted by var. The second form var:Label or var IS Label schedules removal of a label (if present) from the element’s label set. The statement has empty declared type and does not change the working table: incoming and outgoing working record/table types coincide, and the result is omitted.
Remove templates and atoms. We reuse the update context and the notion of an update target introduced for SET. Consider an update pipeline
whose read part yields the bag
of mappings over node, edge, and path variables. Each occurrence of a mapping in is processed separately; hence duplicate mappings may generate duplicate removal atoms.
The construction of the update proceeds in three stages. First, for every mapping occurrence and every remove item , the binding-variable reference contained in is evaluated under :
This target-resolution stage determines the node or edge to which the item refers but does not yet modify the graph. In particular, all targets are resolved with respect to the bindings produced by the read part before the corresponding removal effects are applied.
Second, the resolved items are inspected in textual order. Each item contributes either one concrete removal atom or no atom. Writing for the empty list, let
be the contribution of . The per-binding write-set is the textual-order concatenation
where denotes list concatenation.
Finally, the per-binding write-sets may be folded over all occurrences to give an extensional summary of the removals completed by a successful statement:
This delta notation is not a replacement for the operational order required by REMOVE. Records are processed in current-working-table order and, for each record, remove items are performed in textual order. The applicable label-cardinality check is made immediately after each label item. After every remove item, the graph’s direct constraints are dynamically validated and its conformance to the constraining graph type is checked. An exception stops that ordered execution. Repeated removals remain harmless once the property or label is absent.
The contribution is determined as follows.
-
Property removal var.prop. Let
be the previously resolved target and let be the property name.
If is the null value, then the item has no effect:
If is an invalidated reference, inspecting its property set raises 22G11. Otherwise:
-
if and occurs in the node-property set of , then
-
if and occurs in the edge-property set of , then
-
if is not present in the property set of , then
-
-
Label removal var:Label or var IS Label. Let
be the previously resolved target and let be the label name.
If is the null value, then the item has no effect:
If is an invalidated reference, inspecting its label set raises 22G11. Otherwise:
-
if and , then
-
if and , then
-
if is not contained in the label set of , then
-
Thus, records the removal effects generated by one occurrence of a match, whereas collects the effects generated by the complete match bag. Applying removes the indicated properties and labels without deleting the affected nodes or edges themselves.
Extensional coalescing for REMOVE. For describing the final graph of a successful execution, write-sets generated for different binding occurrences can be summarized using the canonical coalescer :
Because contains only removal atoms, all contributions are pairwise compatible:
- Removing the same property or label from the same element multiple times is idempotent; duplicate atoms may therefore be coalesced into a single removal.
- Removing different properties or labels, whether from the same or different graph elements, commutes; their order does not affect the final graph state.
Consequently, is defined when combining raw write-sets that contain only removal atoms, and there is no analog of the multiple assignments to the same property conflict (status 22G0M) that may arise for SET. This extensional commutativity does not license reordering the operational steps: intermediate label-cardinality and graph-type checks remain observable. A successful REMOVE statement has a uniquely determined summary . This delta may be empty when every remove item resolves to null, or when none of the indicated properties or labels is present; an invalidated reference instead raises 22G11 when its referent is accessed.
Application and label-set cardinalities. Applying to produces a graph in which:
- Every REMOVE_NODE_PROP and REMOVE_EDGE_PROP atom deletes the indicated property from the respective property set, if present.
- Every REMOVE_NODE_LABEL and REMOVE_EDGE_LABEL atom removes the designated label from the respective label set, if present.
Immediately after each label-removal item, the node-label set (resp. edge-label set ) must still satisfy the implementation-defined minimum label-set cardinality. If the resulting cardinality for a node falls below the supported minimum, the statement signals data exception 22G0N; if it falls below the supported minimum for an edge, it signals 22G0Q. These label-set cardinality checks are data-exception rules of the operation. After each remove item, the graph’s direct constraints are dynamically validated. If the containing graph has a constraining graph type but the graph is not of that type, the operation raises G2000; this conformance check includes the constraints of that graph type.
Read stability. A REMOVE statement inherits the same statement-level read stability as SET. All variable references used as l-values in remove-items are evaluated over the incoming working-table records. The removals are then performed in the record and item order described above; is only an extensional summary of a successful final effect. Transaction rollback rules govern the effects of a failed procedure.
14.5 Update Model for Property Graphs
The mutable graph state is the complete property-graph tuple introduced in Chapter 6:
Primitive mutations (expressible using GQL data-modification statements) are modeled as deltas over all of these components:
where and are the new element’s label and property sets, are endpoints, and records whether an edge is directed and, when directed, its orientation. Application of a well-formed delta updates the corresponding components together; deleting a node is defined only when every incident edge is also deleted. A statement therefore denotes a partial transformation . Failure of dynamic validation for a direct constraint in raises 23000. Independently, if the result of a primitive data-modifying statement is not of its constraining graph type, its mandatory conformance check raises G2000.
14.6 Dynamic Constraint Validation
Some DML forms are set-based: effects are computed from the whole input multiset to avoid statement-order anomalies (e.g., key and unique-constraint satisfaction), then applied atomically. After a primitive data-modifying operation, every constraint defined directly on the modified graph is dynamically validated. The graph is then checked for conformance to its constraining graph type, when present; that check includes the constraints of the graph type. Constraints registered for unrelated catalog subjects are not consulted.