GQL Essentials Types and Schemas
PDF ↗

Types, Schemas, and Constraints

Chapter 15Types and Schemas

This chapter introduces the static typing layer of GQL, which constrains the shape of property graphs beyond their raw data model. We describe how property types, node and edge types, and graph types are specified, and how they interact with keys, label tests, and integrity constraints to define admissible graphs.

15.1 Catalog and Name Universes

Universes of names. Let Catalog be the abstract carrier of well-formed hierarchical GQL-catalogs, with C,C′ ∈Catalog. Its internal directory/schema structure is defined in Chapter 17. Let 𝕂 be the (implementation-defined) universe of property keys (identifiers admissible as property names). Let ℕN, ℕE, ℕG be name universes for node types, edge types, and graph types, respectively, and let ℕgraph be the universe of graph entry names. These are schema-local name sets used inside the single hierarchical catalog defined in Chapter 17; they are not additional top-level catalogs. Node and edge types are secondary objects contained in graph types.

15.2 Property Types

Type universe. We reuse the value and type universes 𝕍 and 𝕋 fixed in Section 6.1. Let 𝕋prop ⊆ 𝕋 be the implementation’s supported property value types. We distinguish the selected scalar and collection fragments 𝕋scal and 𝕋coll of this set, with

𝕋scal ∪𝕋coll ⊆𝕋prop.

For τ ∈ 𝕋prop, we write ⟦τ⟧⊆ 𝕍 for its values. Null belongs to this set exactly when τ is nullable.

Scalar types. The selected scalar fragment used below contains (feature-set dependent precisions omitted for brevity)

𝕋num = {INTEGER,BIGINT,DECIMAL(p,s),FLOAT,DOUBLE}, 𝕋bool = {BOOLEAN}, 𝕋text = {STRING}, 𝕋bin = {BYTES}, 𝕋temporal = {DATE,ZONED_TIME,LOCAL_TIME, ZONED_DATETIME,LOCAL_DATETIME, DURATION(YEARTOMONTH),DURATION(DAYTOSECOND)},

𝕋scal is the union of these sets. (Additional scalar value types from the GQL standard can be added without changing the subsequent development.)

Collection types. One collection fragment used below consists of homogeneous list types:

LIST⟨τ⟩∈ 𝕋coll(finite sequences over ⟦τ⟧).

Other supported property value types, including applicable vector, record, and dynamic union types, remain in 𝕋prop as governed by the implementation’s conformance claim.

The denotation function ⟦⋅⟧ : 𝕋 →P(𝕍) assigns to each type the set of admissible values.

Nullability and absence. A property type is a pair consisting of a property name and one supported property value type. Consequently, a declaration k : τ admits exactly values in ⟦τ⟧: it admits a list only when τ is a list type, and it admits null only when τ is nullable. An absent property is not a value and is represented only by the totalized lookup ρ^ from Section 6.2.

Widening preorder and casts. Define the widening preorder ⊒ on value types by

τ1 ⊒ τ0⇔⟦τ0⟧⊆⟦τ1⟧.

A cast from τ0 to τ1 is in general partial, c : ⟦τ0⟧ ⇀ ⟦τ1⟧; failure is reported according to the cast and store-assignment rules. An implicit assignment conversion is admissible only where the GQL assignment rules establish it; widening alone does not invent a conversion. For every successful application,

v ∈dom(c) ⇒c(v) ∈⟦τ1⟧.

Static property signatures. For a type descriptor T (node or edge), its property signature is a finite map

ptypeT : 𝕂 ⇀ 𝕋prop

assigning a supported property value type to each declared property key; the run-time admissible values are given directly by the denotation of that type.

Key label sets (KLS). A key label set is the possibly empty label set, subject to supported cardinality limits, associated with a keyed node or edge type in a graph type. The graph type’s node or edge key-label-set dictionary uses it to identify the corresponding keyed element type. A key label set is not by itself an integrity constraint.

15.3 Node and Edge Types

Label and property sets. Each GQL node or edge type has a fixed label set and a fixed property-type set. We represent the latter as the finite map ptypeT above. Thus type membership uses equality of label sets and property-name sets, not an open label test or a property-closedness switch.

Reduced node-type descriptor representation. In the reduced book-level representation used here, a node type descriptor is represented by the tuple

NDesc = ⟨N,LN,ptypeN⟩,

where N is the local type name, LN ⊆ 𝕃 is its node type label set, and ptypeN is its property signature. Key label sets and named constraints belong to the containing graph type descriptor rather than to this node type descriptor. The fixed primary-base-type name and preferred-name metadata of the full ISO descriptor are elided from this representation.

A node v ∈ V conforms to N (notation: v :: N) iff

(labels) λV (v) = LN; (property names)dom(ρV (v)) = dom(ptypeN); (typing) ∀ ⁡k ∈dom(ptypeN).ρV (v)(k) ∈⟦ptypeN(k)⟧.

For example, the Book node type declared in Section 4.2 is represented by

ptypeBook = {isbn↦STRINGNOTNULL,title↦STRING, author↦STRING},
NDescBook =⟨Book,{Book},ptypeBook⟩.

The node b1 representing Graph DB 101 in Figure 4.1 conforms to Book: its label set is {Book}, its property names are exactly {isbn,title,author}, and each corresponding value belongs to the denotation of its declared type.

Reduced edge-type descriptor representation. In the reduced book-level representation used here, an edge type descriptor is represented by the tuple

ETypeDesc = ⟨ET,LE,kindE,endSpecE,ptypeE⟩,

where ET is the local type name; LE is its edge type label set; kindE ∈{directed,undirected} is its directionality; endSpecE is an ordered source–destination pair of node types in the directed case and a set of one or two endpoint node types in the undirected case; and ptypeE is its property signature. The fixed primary-base-type name and preferred-name metadata of the full ISO descriptor are elided from this representation.

An edge e ∈ E with endpoints (src(e),dst(e)) conforms to ET (notation: e :: ET) iff

(labels) λE(e) = LE; (property names) dom(ρE(e)) = dom(ptypeE); (typing) ∀ ⁡k ∈dom(ptypeE).ρE(e)(k) ∈⟦ptypeE(k)⟧; (kind and endpoints)dir(e) agrees with kindE and the endpoints have the node types in endSpecE,

For a directed type the endpoint check preserves source and destination. For an undirected type it requires the relation between the two endpoints and the one or two endpoint node types to be both left-total and right-total.

For example, let ETinc denote the local type name, in the descriptor model used here, of the directed edge type specification carrying the label INCLUDES in Section 4.2. It is represented by

ptypeinc = {due_date↦DATE,late_fee↦FLOAT},
\begin{aligned}
\mathbf{ETypeDesc}_{\mathsf{inc}}
={}&\bigl\langle
  \mathsf{ET}_{\mathsf{inc}},
  \{\texttt{INCLUDES}\},
  \mathsf{directed},\\
&\langle\texttt{Loan},\texttt{Book}\rangle,
  \mathsf{ptype}_{\mathsf{inc}}
\bigr\rangle.
\end{aligned}

The edge einc,1 in the library instance conforms to this type: its label set is {INCLUDES}, it is directed from the Loan node l to the Book node b1, and its two property values have the declared DATE and FLOAT types.

Element-type implication and structural consistency. GQL does not obtain element-type membership from an open-property inheritance rule. Within one graph type, an element type T1 implies a keyed element type T0 when both have the same element kind, the effective key label set of T0 is a subset of the label set of T1, and the key-label-set conditions of the graph type are met. Structural consistency then requires the label set and property-name set of T0 to be subsets of those of T1, and each pair of same-named property value types to combine to the value type declared by T0 under graph-type-specific combination. Implied edge types must additionally be structurally endpoint-consistent and have the same directionality. This is distinct from the ordinary value-type subtyping relation ⊑ of Section 6.1.

15.4 Graph Types

Reduced structural graph-type descriptor component. In the reduced book-level representation used here, write

Σ = ⟨NDecls,EDecls,NodeKLS,EdgeKLS⟩.

Here NDecls is a finite map from node type names to NDesc, and EDecls is a finite map from edge type names to ETypeDesc. The node key-label-set dictionary NodeKLS maps every node type key label set to its keyed node type; EdgeKLS maps every edge type key label set to the corresponding set of keyed edge types. The declarations must satisfy GQL’s key-label-set implication consistency, property-value-type consistency, and endpoint consistency conditions.

Constraint dictionary (operational part). Let CDesc be the abstract carrier of key and unique constraint descriptors; its components and satisfaction semantics are defined in Chapter 16. A graph type comprises a node type set, an edge type set, and a constraint set. Its reduced descriptor representation pairs Σ with the named constraint dictionary IGT : 𝔸 ⇀ CDesc. See Section 15.5 below for this pair and its use in catalog entries.

Example: libraryGraphType. Let NDeclslib and EDeclslib be the descriptor maps induced by the node- and edge-type declarations in Section 4.2. In particular,

NDeclslib(Book) = NDescBook,EDeclslib(ETinc) = ETypeDescinc.

The key-label-set dictionaries are

NodeKLSlib = {{Loan}↦Loan, {LibraryAccount}↦LibraryAccount, {Reader}↦Reader, {LibraryCard}↦LibraryCard, {Book}↦Book}, EdgeKLSlib = ∅.

Hence the static schema is

Σlib = ⟨NDeclslib,EDeclslib,NodeKLSlib,EdgeKLSlib⟩.

The associated constraint dictionary Ilib satisfies

dom(Ilib) = {LoanHasKey,LibraryAccountHasKey,ReaderHasKey, LibraryCardHasKey,BookHasKey},

and each name maps to the key-constraint descriptor induced by the corresponding declaration in Section 4.2.

15.5 Graph Entries and Constraining Types

Constraining graph type descriptor. In the reduced book-level representation used here, a GTypeDesc is the pair ⟨Σ,IGT⟩, where Σ is the structural descriptor component above and IGT maps each constraint name to its key or unique constraint descriptor. The fixed primary-base-type name and preferred-name metadata of the full ISO descriptor are elided from this representation.

A graph G is of the graph type described by GTypeDesc = ⟨Σ,IGT⟩ exactly when every node of G is of a node type in NDecls, every edge is of an edge type in EDecls, and every constraint of the graph type is satisfied. There is no independent “open labels” or “open properties” policy inside a graph type; openness instead means that a graph has no constraining graph type.

Graph entries. A catalog graph entry abstracts the ISO graph descriptor as

GraphEntry = ⟨G,GT?,I G⟩,

where G is the instance graph, GT? is either a globally resolved graph type reference or none (no constraining graph type), and IG maps names to constraints defined directly on G. If GT? = GT, constraint names are unique independently of their origin, so

dom(IG) ∩dom(IGT) = ∅.

For the library graph created in Section 4.2 and populated in Section 4.3, let Glib denote the resulting graph instance and let GTlib be the globally resolved graph type reference denoted by libraryGraphType. Since the example declares no constraints directly on the graph, its catalog entry is

GraphEntrylib = ⟨Glib,GTlib,∅⟩ .

The empty third component means only that the graph has no directly defined constraints. The key constraints contained in the resolved libraryGraphType still apply through the constraining graph type reference in the second component.

Catalog location. Cataloged graph types and cataloged graphs are primary objects held by a GQL-schema in the single catalog C of Chapter 17. Inline graph types and unnamed graphs can also be primary objects without being catalog objects. Node and edge type descriptors are secondary objects contained in a graph type; they are not parallel top-level catalog dictionaries.

Resolution. Name resolution is modeled by partial functions that consult C. For graph types, write

resolveGraphType(C,GT) = ⟨ΣGT,IGT⟩

when the graph type reference identifies that descriptor in its parent GQL-schema.

Graph-entry conformance. Write G⊧strΣ when every node and edge of G satisfies the applicable label, property, directionality, and endpoint requirements encoded by the node and edge type declarations in Σ. For a set J ⊆CDesc, write G⊧conJ when G satisfies every key or unique constraint descriptor in J, with satisfaction as specified in Section 16.1. For GE = ⟨G,GT?,I G⟩∈GraphEntry, let

Idirect(GE) = ran(IG)

be the constraints defined directly on the graph. For bookkeeping, the set of all constraints registered for the graph is

Iactive(GE) = ran(IG)∪ { ran(IGT),GT? = GT, ∅, GT? = none.

but dynamic validation retains the two origins. The constraints in Idirect(GE) are validated directly. If GT? = GT, resolution must succeed and the separate test that G is of its constraining graph type requires

G⊧strΣGT ∧G⊧conran(IGT).

Every graph must additionally satisfy G⊧conIdirect(GE). A graph with a constraining graph type is closed; a graph with GT? = none is open. Constraints apply only to their registered subjects, so constraints collected for a different graph entry or graph type are never included in Iactive(GE).

15.6 DDL Semantics

General form. A DDL statement D denotes a partial function

⟦D⟧ : Catalog ⇀ Catalog

for the catalog-modifying statements modeled here. A successful result must be a well-formed hierarchical catalog. In particular, every surviving GraphEntry must still resolve its optional constraining graph type and satisfy its active graph-type and graph constraint dictionaries at the required validation point.

Node and edge type definitions. This edition of GQL has no standalone CREATE NODE TYPE or CREATE EDGE TYPE catalog-modifying statement. Node and edge type specifications are secondary objects created as body items of a graph type.

Creating graph types. The concrete syntax of CREATE GRAPH TYPE statements is governed by the core GQL grammar (where graph types are catalog objects whose bodies enumerate node types, edge types, and optional schema-level constraints). The following abbreviated BNF preserves the alternatives relevant here; the node- and edge-type nonterminals are the pattern/phrase forms of the core grammar:

BNF
create-graph-type-stmt ::=
  "CREATE" ( [ "PROPERTY" ] "GRAPH" "TYPE" [ "IF" "NOT" "EXISTS" ]
             | "OR" "REPLACE" [ "PROPERTY" ] "GRAPH" "TYPE" )
  catalog-graph-type-parent-and-name graph-type-source

graph-type-source ::= [ "AS" ] nested-graph-type-spec
                    | [ "AS" ] "COPY" "OF" graph-type-reference
                    | "LIKE" graph-expression

nested-graph-type-spec ::= "{" graph-type-body-item
                               { "," graph-type-body-item } "}"

graph-type-body-item ::= node-type-spec
                       | edge-type-spec
                       | "CONSTRAINT" constraint-spec

node-type-spec ::= node-type-pattern | node-type-phrase
edge-type-spec ::= edge-type-pattern | edge-type-phrase

property-types-spec ::= "{" [ property-type
                                   { "," property-type } ] "}"

property-type ::= property-name [ ( "::" | "TYPED" ) ] property-value-type

Semantically, a create-graph-type-stmt introduces a named graph type whose node- and edge-type items populate NDecls and EDecls of a tuple Σ as defined above, while each property-type contributes an entry to the corresponding property signature ptypeT . Each CONSTRAINT item populates IGT with a named key or unique constraint. The resulting graph type may be used as a constraining type in catalog graph entries as described in Section 15.5. A complete CREATE GRAPH TYPE statement using node types, edge types, property signatures, and key constraints appears in Section 4.2.

Alteration and conversion. The ISO standard defines creation, replacement, and dropping of graph types, but no ALTER TYPE, ALTER PROPERTY, ADD KEY, or DDL USING conversion clause. Such schema/data migration is therefore outside this core semantics. Whenever a value is assigned or explicitly cast by supported GQL syntax, the cast and store- assignment rules apply and may raise an exception; no type-set inclusion makes that conversion total by itself.

Dropping declarations. The core drop operation here is DROP [PROPERTY] GRAPH TYPE [IF EXISTS] q. It is permitted only when no existing graph in the catalog references that graph type. On success the descriptor is removed from its parent schema and destroyed. Consequently the operation neither silently changes the property type of existing data nor requires an invented property-level cast. OR REPLACE first performs this same drop and is subject to the same reference condition.

15.7 Schema Versioning

Scope. Let Sch be the current schema state extracted from the catalog and Sch′ a schema state produced by a supported evolution step. ISO 39075 leaves it implementation-defined which catalog-modifying procedures are under transaction control and uses a feature to govern whether data modification and catalog modification may appear in the same transaction. Where an implementation supports transactional DDL and such mixing, we model schema evolution as producing a new schema state Sch′ from Sch.

Schema states and versions. DDL commands produce a chain

Sch(0) →DDL 1Sch(1) →DDL 2⋯ →DDLnSch(n).

Whether these catalog changes participate in a transaction and any physical reorganization are implementation-defined. The standard’s statement-specific validation and execution rules remain controlling; the formal development assumes a conforming catalog state after each successful committed step.

GQL Essentials · Dominik Tomaszuk

Search chapters, definitions and examples.