Chapter 08Expressions and Evaluation
This chapter specifies how GQL expressions are typed and evaluated with respect to the current database state (store state) and the relevant environments. It makes explicit the interaction between value domains, implicit casts, errors, and three-valued logic, and clarifies how nulls affect the outcome of expression evaluation.
8.1 Expression Domains
Let denote the store state. A row environment for evaluating expressions in the context of a record is a partial mapping
and undefined for . A global environment binds constants (catalog objects, procedures, named graphs, types, etc.). An evaluation environment is the pair .
8.2 Typing and Evaluation
Typing and casting. Let denote the statically derived typing judgment that expression has type . A (partial) implicit cast relation determines where a value of type may be coerced to at use sites (e.g., integer decimal). We write when the coerced value exists.
Evaluation judgment. Using the abstract error carrier declared in Chapter 6, whose tokens include, for example, division-by-zero, type-mismatch, and overflow, we write
where . Evaluation is total into but may yield errors (note that ). When is a record, is the row environment induced by , and are fixed by the surrounding context, we use the abbreviation
For a Boolean expression , denotes the corresponding member of , or an element of , under the same convention.
Evaluation order. ISO/IEC 39075 specifies expression results through the General Rules but does not classify built-in functions as , , or . Unless precedence, parentheses, or a specific General Rule determines otherwise, effective evaluation is generally from left to right; whether expressions are actually evaluated in that order is implementation-dependent, particularly when an operand can raise a condition or when the result can be obtained without evaluating every part. Consequently, no stronger repeatability or evaluation-order guarantee is assumed here than the guarantee stated for the particular expression in the standard.
8.3 Truth Values and NULL
Three-valued logic. Boolean contexts range over the three-valued domain fixed in Section 6.1,
read as true, false, and unknown, respectively. The connective tables follow Kleene’s strong three-valued logic; for example:
In concrete GQL, the abstract truth values and correspond to the Boolean constants TRUE and FALSE, and is represented by the Boolean null value, as specified in the standard; here, is used as an abstract carrier for the three-valued semantics. A comparison () evaluates to if either operand is . Predicates such as IS NULL and IS NOT NULL are two-valued (they never yield ).
Example (a library evaluation judgment). Let denote an edge reference value whose referent is the second INCLUDES edge . Let the current row bind that reference:
For the library store state ,
Ordering and sorting. For each base type whose values admit ordering, let denote the corresponding weak order. Values of different types are compared only when their types are comparable, possibly after applying permitted implicit casts to a common comparable type. If universal comparison is supported, values that are not otherwise comparable may instead be ordered according to an implementation-defined total order that remains stable throughout the execution of a GQL request.
The ordering used by ORDER BY additionally determines the placement of through either NULLS FIRST or NULLS LAST. This placement rule is specific to sorting: comparisons of with a material value using or yield , rather than treating as smaller or greater than that value.
Domains. Let denote the (countable) universe of graph-pattern and scalar variables. A (variable) mapping is a partial function
We thus distinguish two forms of absence: (i) unbound variables, i.e., those for which is undefined, and (ii) the distinguished constant among scalar values. Expressions may evaluate to a value (including ), or they may raise a runtime error .
Truth values and evaluation. A predicate (Boolean) expression is evaluated under a mapping and graph as
Atomic comparisons use SQL-style three-valued logic:
In particular, the result is if either operand is . Equality of lists and records is determined recursively, so a material list or record containing a null value can also produce : an unequal component decides , all components equal decide , and an otherwise undecided component comparison gives . The other comparison operators follow their standard transformations and ordering rules; non-comparable operands raise the specified data exception. If evaluation of a required sub-expression raises , evaluation of the comparison raises the corresponding dynamic exception. The treatment of an error in an inessential part of a containing expression follows the implementation-dependent rule described below.
Connectives. We use Kleene’s strong truth tables:
These tables determine the result but do not impose operational short-circuiting. For example, after in a conjunction or in a disjunction, the other operand is inessential to the truth value. If evaluating such an inessential part would raise an exception, ISO/IEC 39075 leaves it implementation-dependent whether that exception is raised.
Null-intolerant and null-tolerant predicates. The null behavior of each built-in is determined by its rules in the standard. As derived terminology in this formalization, a function is strict if any argument yields . A predicate is null-intolerant if any argument yields . Non-strict/total built-ins may map to a concrete value (e.g., ).
Null predicates for composites (conformance). For list and record values the null check also includes IS [NOT] CONTAINING NULL, which inspects elements/fields for the presence of ; availability of this predicate follows the corresponding conformance feature in the GQL standard.
SAME predicate. The optional SAME predicate (Feature G114) takes at least two permitted arguments; generalized arguments require Feature G117. If an argument is null, it raises 22004, and if two arguments are not comparable, it raises 22G04. Otherwise, its result is exactly when every pair of arguments compares equal, and otherwise.
Filtering. For a bag of mappings, the WHERE filter is
and is undefined (signals a dynamic exception) if for any .